在跨域ajax请求中使用一些旧浏览器传递自定义头
考虑到以下跨域请求(Safari 5.0.2中的可复制f.ex.,任何操作系统): 请求在跨域ajax请求中使用一些旧浏览器传递自定义头,ajax,iis,http-headers,cors,Ajax,Iis,Http Headers,Cors,考虑到以下跨域请求(Safari 5.0.2中的可复制f.ex.,任何操作系统): 请求 var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://myhost.tld/odata/Account(518059)', false); xhr.setRequestHeader('Authorization','Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJsb2phYWxpLXdl
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://myhost.tld/odata/Account(518059)', false);
xhr.setRequestHeader('Authorization','Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJsb2phYWxpLXdlYmFwaS5jbG91ZGFwcC5uZXQiLCJleHAiOjEzOTQxMjM2MzcsImlzcyI6IldlYkFwaSIsImNhbXBJZCI6MjksInBvcnRhbElkIjozMiwidXNlcklkIjo1MTgwNTl9.c8223aYpb4X7kwYLSmSSQr4wGytxcYtOzTlQuHa9mYU');
xhr.send();
xhr.responseText;
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://myhost.tld/odata/Account(518059)', false);
xhr.send();
xhr.responseText;
响应
Error: NETWORK_ERR: XMLHttpRequest Exception 101
{
'odata.metadata': 'http://myhost.tld/odata/$metadata#Account/@Element',
'Id': 518059,
'userName': '643033849'
}
标题
OPTIONS /odata/Account(518059) HTTP/1.1
Host: myhost.tld
Accept: */*
Accept-Language: en-US
Access-Control-Request-Method: GET
Origin: http://myclient.tld
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.2; en-US) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5
Accept-Encoding: gzip, deflate
Access-Control-Request-Headers: Authorization
Content-Length: 0
Connection: keep-alive
Connection: keep-alive
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.5
Access-Control-Allow-Origin: http://myclient.tld
Access-Control-Allow-Methods: GET
Access-Control-Allow-Headers: Authorization
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 06 Mar 2014 16:37:26 GMT
Content-Length: 0
我验证了WebAPI正确地处理了请求,并且确实使用HTTP200返回了数据。但是,在一些较旧的浏览器上,请求似乎失败了。因此,我继续在服务器端硬编码授权令牌,并将其从等式中删除,然后:
请求
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://myhost.tld/odata/Account(518059)', false);
xhr.setRequestHeader('Authorization','Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJsb2phYWxpLXdlYmFwaS5jbG91ZGFwcC5uZXQiLCJleHAiOjEzOTQxMjM2MzcsImlzcyI6IldlYkFwaSIsImNhbXBJZCI6MjksInBvcnRhbElkIjozMiwidXNlcklkIjo1MTgwNTl9.c8223aYpb4X7kwYLSmSSQr4wGytxcYtOzTlQuHa9mYU');
xhr.send();
xhr.responseText;
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://myhost.tld/odata/Account(518059)', false);
xhr.send();
xhr.responseText;
响应
Error: NETWORK_ERR: XMLHttpRequest Exception 101
{
'odata.metadata': 'http://myhost.tld/odata/$metadata#Account/@Element',
'Id': 518059,
'userName': '643033849'
}
瞧,它突然开始工作了。所以,我把整个互联网下载到我的硬盘上并阅读了它,但找不到f.ex。较旧的Safaris不支持跨域请求的自定义头,我也无法找到可能的解决方案,而无需进入明显的Http处理程序或JSONP路由
所以,除了上面提到的“修复”,我还可以做些什么来安全地将这个令牌从我的客户机传输到服务器,从而避免自定义头。或者,有没有办法让它们发挥作用
饼干?
请不要这样建议。一些Safari版本,包括5.0.2,除非用户访问了跨域请求的目标站点,否则会阻止跨域cookie。最终,我发现没有办法实际修复这种情况。与此类似,一些旧版本的浏览器根本不支持在CORS请求中传递自定义头。由于我们在身份验证中使用Json Web令牌,我真的需要这样做 因此,我在
IIS
中找到了这个应用程序请求路由(ARR)
模块,它使用URL Rewrite
引擎创建反向代理。更具体地说,将^/odata(.*)$
下的所有请求映射到我的后端web api主机
以下是配置反向代理的高级步骤
打开IIS管理器
露天场地
在“功能”视图中,选择“URL重写”(前提是它已安装)
选择“添加规则”
在入站和出站规则中,选择反向代理
如果您没有安装应用程序请求路由(ARR),它将提示您这样做,接受
创建将路径映射到后端服务器的规则
保存后,规则将写入Web.config
<rewrite>
<rules>
<rule name="ODataApiReverseProxy" stopProcessing="true">
<match url="^odata(.*)$" />
<action type="Rewrite" url="http://webapi.host.tld/{R:0}" />
</rule>
</rules>
<outboundRules>
<rule name="ODataRewriteJson" preCondition="ResponseIsJson" patternSyntax="ExactMatch">
<match filterByTags="None" pattern="webapi.host.tld" />
<action type="Rewrite" value="client.host.tld" />
</rule>
<preConditions>
<preCondition name="ResponseIsJson">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^application/json" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
现在,客户端将完全跳过CORS预飞行,因为它连接到同一主机。此外,ARR在配置、缓存、负载平衡、监视和管理等方面允许更多