在跨域ajax请求中使用一些旧浏览器传递自定义头

在跨域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

考虑到以下跨域请求(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.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在配置、缓存、负载平衡、监视和管理等方面允许更多