以前解决过很多异步请求跨域的问题,自认为不会有什么难点,可今天调试一个项目API的时候遇到了之前没遇到的问题,弄了好久才解决,记录如下:
项目中涉及一个主域(以www.abc.com表示),子域(以s.abc.com表示),子域控制器s.abc.com/Action向主域www.abc.com/Reply发异步POST请求,www.abc.com/Reply发出Header参数“Access-Control-Allow-Origin:http://s.abc.com““Access-Control-Allow-Methods:POST”,按理说这应该没什么问题了,但问题来了:
1. 直接访问通过URL:www.abc.com/Reply访问,可以看到添加的“Access-Control-Allow-Origin“等响应头,也能正常传递JSON,如下:
Access-Control-Allow-Methods: POST Access-Control-Allow-Origin: http://s.abc.com Access-Control-Expose-Headers: Authorization Content-Encoding: gzip Content-Length: 138 Content-Type: text/json; charset=utf-8 Date: Wed, 27 Mar 2019 07:03:09 GMT Server: Tengine Vary: Accept-Encoding
2. 但通过子域的AJAX请求,死活就得不到添加的Headers参数,FF及Chrome均提示提示同源错误“原因:头缺少 ‘Access-Control-Allow-Origin’”,明明已经设置,就是没有传递,而之前做的一个接口几乎代码一样,但却能正常返回值,确实让人百思不得其解。
无奈之下,只能检查服务器设置,发现URLrewrite有如下规则:
<rule name="LowerCaseRule1" stopProcessing="true"> <match url="[A-Z]" ignoreCase="false" /> <action type="Redirect" url="{ToLower:{URL}}" /> </rule>
恍然大悟!
这个是SEO常设规则,用来规避因为URL大小写而带来搜索引擎识别为不同站点的问题,而项目很多CLASS命名都根据大小驼峰规则,Controls也是大小混写,这条重写规则强制将文件名小写返回,而AJAX请求则认为是两个不同请求,导致Headers参数无法正常接收。
取消此规则,问题解决。