假设我控制了两个域,www.api_domain.com
和www.website_domain.com
。 www.api_domain.com
提供了一个API,要求用户进行身份验证,然后使用会话cookie来识别发出请求的用户。 www.website_domain.com
将脚本从www.api_domain.com
加载到其网页上,该脚本希望使用当前用户的Cookie调用www.api_domain.com
上的API网址,并在{{}}页面上以某种方式使用结果{ {1}}。
对于最初加载脚本或任何不需要用户会话cookie工作的API URL,最简单的解决方案就是使用
www.website_domain.com
来自Access-Control-Allow-Origin: http://www.website_domain.com
的回复标题。这似乎在除了IE之外的所有浏览器上开箱即用,虽然IE不会尊重使用jQuery的AJAX方法制作的AJAX请求的Allow-Origin标头,但是像xdr.js这样的库在幕后做了一些魔术。使jQuery,IE和Allow-Origin标头一起玩得很好,并且在所有其他浏览器中表现得像(我不知道xdr.js的详细信息,但就我所见,它对于非凭证请求非常有效) )。
当我想在www.api_domain.com
上点击需要用户会话cookie的网址时出现问题。当在浏览器无关的设置中讨论此问题时,通常会提出两种解决方案:
http://www.api_domain.com
即使有跨域请求也可以发送cookie。 Access-Control-Allow-Credentials: true
的页面上创建iframe
http://www.website_domain.com
,让两个窗口进行通信
彼此使用HTML5 post messages并委托所有人
向http://www.api_domain.com
提出请求的责任
iframe。如果可能的话,我更倾向于使用选项1,因为它允许您编写Javascript代码以使用http://www.api_domain.com
上的API,就像您将其编写为触摸同域API一样。要使用iframe方法,我们需要学习或创建一些框架,用于向iframe发送类似AJAX的请求,以及成功和错误处理程序。这也意味着我们需要创建要加载到iframe中的代码,iframe只是用于访问API URL的一大堆精简包装器。与第一种方法相比,它看起来更丑陋,更难理解,更难理解。
但是,我无法弄清楚如何让选项1在IE上运行。我在我的API网址上设置了http://www.api_domain.com
,而所有其他浏览器都向这些网址发送了Cookie,但IE 9却没有,即使使用xdr.js库也是如此。 (我没有在IE 8上测试过。)没有任何其他症状需要报告。当我在IE的开发人员工具中查看时,我可以在Access-Control-Allow-Credentials: true
的响应中看到正确的Access-Control-Allow-Origin
和Access-Control-Allow-Credentials
标头,但请求中没有Cookie标头。
我是否可以使用一些黑客或魔法咒语来使Internet Explorer尊重www.api_domain.com
标题,或IE可识别的其他标题?
答案 0 :(得分:9)
在IE9或更低版本中无法使用选项1,因为使用XMLHttpRequest不支持CORS。此外,如果您尝试使用XDomainRequest,您将永远无法发送任何cookie以及您的请求。我一直在这条路上工作,编写一个ui测试库,用于testwarm。你想做的就是不可能以这种方式。
这是前微软开发人员Eric Law的一篇文章,详细讨论了这个问题: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
相关部分明确指出,在IE 8和9中无法发送带有CORS请求的cookie,如下所示:
在Internet Explorer 8中,引入了XDomainRequest对象。此对象允许AJAX应用程序直接通过确保HTTP响应只能由当前页面读取(如果数据源指示响应是公共的)来直接发出安全的跨源请求。这样,同源策略安全保证受到保护。响应表明他们愿意通过将Access-Control-Allow-Origin HTTP响应头包含值*或调用页的确切来源来允许跨域访问。
在设计新对象时,确保现有网站和服务不会受到威胁是我们的首要任务。为此,我们对可以使用XDomainRequest对象进行哪种请求施加了一些限制。
...
5:不会随请求一起发送身份验证或cookie
为了防止滥用用户的环境权限(例如cookie,HTTP凭据,客户端证书等),请求将被剥夺cookie和凭据,并将忽略HTTP响应中的任何身份验证质询或Set-Cookie指令。 XDomainRequests不会在以前经过身份验证的连接上发送,因为某些Windows身份验证协议(例如NTLM / Kerberos)是基于每个连接而不是基于请求的。
希望对跨源请求执行用户身份验证的站点可以使用显式方法(例如POST正文或URL中的令牌)来传递此身份验证信息,而不会冒用户的环境权限。
现在假设你控制了两个位置,你可能会创建一个服务器到服务器的身份验证过程,然后通过你的请求传递从域提供的其他域的会话ID。它不漂亮,但它的工作原理。文章中也提到了这种方法。你会想要小心,因为它开启了会话劫持的可能性。
答案 1 :(得分:0)
IE8 +可替代XMLHttpRequest
,支持XDomainRequest
凭据。无论如何,XDomainRequest
不是由JQuery实现的,因为它的功能少于XMLHttpRequest
提供的功能,但有像jQuery CORS Plugin这样的插件可以提供你需要的东西。
jQuery插件,它透明地添加了跨源资源共享 (CORS)浏览器(包括IE8 +)允许跨域Ajax 请求使用Cookie和标头支持。
我认为但不确定IE在Access-Control-Allow-Origin: *
这样的标题中不支持通配符。