请在401时帮助测试Firefox jQuery ajax中的CORS问题

这让我疯狂。

jQuery 1.4.2,windows XP sp3

这是我的考试。

加载Firefox 3.5+

http://plungjan.name/test/testcors.html

作品

将文件保存到硬盘并从那里运行

从我的办公室外部工作和内部工作没有

同样有趣的是,我不能一气呵成。

背景:我对使用CORS的内部Web服务进行了GET 。 请不要发布有关FF的任何答案,因为这里和此处详细介绍了自v3.5以来的处理跨域请求

它可以在IE8和FF3.6.6中从一台服务器运行到另一台服务器,现在几乎从文件系统(文件:///)到服务。 仅从文件系统和当FF 3.6.6需要协商(用户已经登录,授权并发送凭证!)时 ,我是否在协商后得不到数据。 jQuery xhr返回状态0,没有data / responseText或者其他什么对我来说,jQuery会对401的xhr作出反应并保存xhr而不是200以后的OK

这是我在提醒XHR对象时在通信结束时得到的结果:

Status:success Data:[] XHR: some native functions, readyState:4 status:0 responseXML:null responseText: withCredentials:true 

如果我调用同一台服务器但不需要凭据,则返回的数据就是精确的跨域

所以沟通如下:

 GET /restapplicationusingcors/authenticationneeded-internal/someid Accept: application/json Accept-Language: en . . Origin: null Cookie: LtpaToken=... 

回报是

 HTTP/1.1 401 Unauthorized Server: Apache Pragma: No-cache Cache-Control: no-cache Expires: Thu, 01 Jan 1970 01:00:00 CET WWW-Authenticate: Negotiate Connection: close Transfer-Encoding: chunked Content-Type: text/html 

然后FF发送

 GET /restapplicationusingcors/authenticationneeded-internal/someid HTTP/1.1 Host: myhost.myintranet.bla User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 Accept: application/json Accept-Language: en Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive Origin: null Cookie: LtpaToken=.... Authorization: Negotiate .... 

并获得我需要的文件奖励,但无法获得FF:

 HTTP/1.1 200 OK Date: Tue, 20 Jul 2010 12:08:39 GMT Pragma: No-cache Cache-Control: no-cache, max-age=600, s-maxage=3600 Expires: Thu, 01 Jan 1970 01:00:00 CET X-Powered-By: ... Content-Disposition: inline;filename=nnnnnn.json Content-Language: en Access-Control-Allow-Origin: ... Keep-Alive: timeout=6, max=70 Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: application/json;charset=UTF-8 

来自服务器的数据不在XHR对象中

这是我的代码

 function getJSON(url,func,lang) { accept = 'application/json'; lang=lang?lang:"*"; // gruesome hack to handle that APPENDS the mime header to */* !!! // NOW HANDLED by first setting Accept to "" !!! // if ($.browser.msie && url.indexOf('serveAsMime')==-1) { // url+= '?serveAsMime='+accept; // } if (currentRequest != null) currentRequest.abort(); var requestObjectJSON = { url : url, // dataType: "json", method : 'get', beforeSend: function(xhr){ xhr.setRequestHeader('Accept', ""); // IE hack xhr.setRequestHeader('Accept', accept); xhr.setRequestHeader('Accept-Language', lang); if (url.indexOf('-internal') !=-1) { try { xhr.withCredentials = true; alert('set credentials') } catch(e) { alert('cannot set xhr with credentials') } } }, success: function(data,status,xhr) { var responseText = xhr.responseText; var responseJSON = xhr.responseJSON; var t = ""; try{ for (var o in xhr) t += '\n'+o+':'+xhr[o]; } catch(e) { if (e.message.indexOf('.channel')==-1)alert(e.message); } alert('Status:'+status+'\nData:['+data+']\nXHR:'+t); func(responseText); }, } currentRequest = $.ajax(requestObjectJSON); } 

这是一个黑暗的刺,因为我不完全理解你的问题,但我认为你可能有file:的问题file: URL,不被视为有任何来源。 我不确定甚至可以从文件URL授权CORS。

因此,您需要在模型/集合中设置ajax预filter才能使用CORS。 否则它不会发送cookie。

 $.ajaxPrefilter( function( options, originalOptions, jqXHR ) { options.xhrFields = { withCredentials: true }; }); 

我把它放在我的Model / Collection初始化函数中。

这些是使CORS使用安全服务所要满足的条件:

  • 服务响应应包含标头Access-Control-Allow-Credentials: true (请参阅具有凭据的请求,并且当凭证标志为true时 , 不能在Access-Control-Allow-Origin中使用通配符 )。
  • 服务响应头Access-Control-Allow-Origin不应该是* 。 我们的想法是返回客户端在头文件中传递的值(参见本文中的示例)。
  • 根据规范, OPTIONS方法应返回HTTP代码200,因此无法保护(参见CORS )。
  • 对于需要将某些请求标头传递给服务的方法PUT / POST (如Content-TypeAccept ),这些标头需要在Access-Control-Allow-Headers列出(请参阅jQuery AJAX在指定标头时无法工作 )
  • JavaScript应该设置此XMLHttpRequest属性: xhr.withCredentials = true; (由柯比回答)

完全配置Apache:

 # Static content: SetEnvIf Request_URI ".*" no-jk # RESTful service: SetEnvIf Request_URI "^/backend/" !no-jk SetEnvIf Request_Method "OPTIONS" no-jk # Fallback value: SetEnv http_origin "*" SetEnvIf Origin "^https?://(localhost|.*\.myconpany\.org)(:[0-9]+)?$" http_origin=$0 Header set Access-Control-Allow-Credentials "true" Header set Access-Control-Allow-Origin "%{http_origin}e" Header set Access-Control-Allow-Methods "GET,POST,PUT,DELETE" Header set Access-Control-Allow-Headers "Content-Type, Accept" JkMount /* loadbalancer 

CORS与file://

如果您通过允许来自file://协议的来源而遇到问题,则根据Web Origin Concept,它应该以与任何其他来源相同的方式完成。 我找不到有关浏览器支持的信息,但我认为每个支持CORS的浏览器都支持这个。

Web Origin Concept告诉我们关于文件URI方案的以下内容:

  4. If uri-scheme is "file", the implementation MAY return an implementation-defined value. NOTE: Historically, user agents have granted content from the file scheme a tremendous amount of privilege. However, granting all local files such wide privileges can lead to privilege escalation attacks. Some user agents have had success granting local files directory-based privileges, but this approach has not been widely adopted. Other user agents use globally unique identifiers for each file URI, which is the most secure option. 

根据维基百科 ,文件URI方案的域名是localhost。 它可以被地址栏省略,但我不认为它在allow origin标题中是可以省略的。 因此,如果您的浏览器实现允许带有文件URI方案的源,那么您应该将file://localhost添加到您允许的来源,之后一切都应该正常工作。

这就是它应该如何工作,现在满足现实:

  • 我用当前的firefox 29.0.1进行了测试,但它没有用。 但是, file://协议通过此实现转换为null原点。 所以通过firefox null工作。 我尝试使用更广泛的域名列表,但我没有设法允许多个域名。 似乎firefox目前不支持包含多个域的列表。
  • 我测试了chrome 35.0.1916,它的工作方式与firefox相同。
  • 我用msie 11.0.9600进行了测试。 根据文件协议的请求,它总是显示allow blocked content按钮,即使不允许空原点。 通过其他域,它的工作方式与以前的浏览器相同。

HTTP基本身份validation:

我尝试使用PHP和HTTP基本身份validation的凭据部分。

HTTP://test.loc
显示:-)登录时:-(未经授权时。

 :-('; } if (!isset($_GET['logout']) && authorized()) { echo ':-)'; } else unauthorized(); 

因此,此代码通过登录和注销更改位置。

跨域CORS与HTTP基本身份validation

HTTP://todo.loc
获取具有跨域 XHR的http://test.loc的内容并显示它。

 cross domain ajax

需要http://test.loc标题:

 Access-Control-Allow-Origin: http://todo.loc Access-Control-Allow-Credentials: true 

使用HTTP基本身份validation的交叉方案CORS

文件:///path/x.html
获取具有交叉方案 XHR的http://test.loc的内容并显示它。

 cross scheme ajax

需要http://test.loc标题:

 Access-Control-Allow-Origin: null Access-Control-Allow-Credentials: true 

结论:

我使用从file://调用的凭据测试了交叉sheme CORS,它在firefox,chrome和msie中运行良好。