Cor*_*son 26 google-chrome cors
从Chrome版本37开始,即使所有CORS标头都设置正确,如果服务器启用了身份验证,预先发布的跨域请求也会失败(再次).这是localhost(我的开发PC).
你们中的一些人可能知道Chrome/CORS/auth错误的历史,特别是涉及HTTPS时.我的问题并没有涉及HTTPS:我有一个AngularJS应用从供应localhost:8383交谈一个Java(码头)的服务器上localhost:8081有HTTP基本身份验证激活.GET工作正常,但POST失败了401:
XMLHttpRequest cannot load http://localhost:8081/cellnostics/rest/patient.
Invalid HTTP status code 401
Run Code Online (Sandbox Code Playgroud)
我之前编写了一个自定义(Java)CORS过滤器,它设置了正确的CORS头,直到第36版.它在v37和最新的v38(38.0.2125.101 m)中失败.它仍然可以按预期使用Internet Explorer 11(11.0.9600)和Opera 12.17(build 1863).
GET请求成功,但POST失败.由于内容类型:"application/json",Chrome看起来像是在推出我的所有POST,并且它是预先发布的OPTIONS请求失败.
在Angular应用程序中,我明确设置了以下请求标头.AFAIK此设置withCredentials应确保即使对于OPTIONS请求也会发送凭据:
//Enable cross domain calls
$httpProvider.defaults.useXDomain = true;
//Send all requests, even OPTIONS, with credentials
$httpProvider.defaults.withCredentials = true;
Run Code Online (Sandbox Code Playgroud)
以下是请求/响应.您可以看到Access-Control-Allow-Methods标题中启用了OPTIONS方法.您还可以看到Javascript应用程序的来源已明确启用:Access-Control-Allow-Origin: http://localhost:8383.
Remote Address:[::1]:8081
Request URL:http://localhost:8081/cellnostics/rest/medicaltest
Request Method:OPTIONS
Status Code:401 Full authentication is required to access this resource
Request headers:
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,af;q=0.6
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:localhost:8081
Origin:http://localhost:8383
Referer:http://localhost:8383/celln-web/index.html
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.101 Safari/537.36
Response headers:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With, Accept
Access-Control-Allow-Methods:POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin:http://localhost:8383
Access-Control-Max-Age:3600
Content-Length:0
Server:Jetty(8.1.8.v20121106)
WWW-Authenticate:Basic realm="Cellnostics"
Run Code Online (Sandbox Code Playgroud)
有谁知道我还应该做些什么?我确保在测试,重新启动之前清除Chrome缓存,并确保在重新启动之前没有后台Chrome进程保持运行,因此我非常确定没有遗留的身份验证缓存问题.
我不得不切换到IE 11来测试我的Web开发.事实上,相同的客户端和服务器设置仍适用于IE和Opera,以及存在Chrome/CORS错误的历史,这让我怀疑Chrome.
编辑:以下是Chrome net-internals事件列表的摘录:
t=108514 [st=0] +URL_REQUEST_START_JOB [dt=4]
--> load_flags = 336011264 (BYPASS_DATA_REDUCTION_PROXY | DO_NOT_SAVE_COOKIES | DO_NOT_SEND_AUTH_DATA | DO_NOT_SEND_COOKIES | MAYBE_USER_GESTURE | VERIFY_EV_CERT)
--> method = "OPTIONS"
--> priority = "LOW"
--> url = "http://localhost:8081/cellnostics/rest/patient"
...
t=108516 [st=2] HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> OPTIONS /cellnostics/rest/patient HTTP/1.1
Host: localhost:8081
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:8383
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.101 Safari/537.36
Access-Control-Request-Headers: accept, content-type
Accept: */*
Referer: http://localhost:8383/celln-web/index.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,af;q=0.6
Run Code Online (Sandbox Code Playgroud)
因此,即使我明确设置,看起来Authorization标头也不会与OPTIONS pre-flight一起发送withCredentials = true.
但是,为什么IE和Opera仍然可以工作?Chrome在这方面是否更符合标准?为什么它会起作用然后从v37开始失败?
编辑:Chrome开发工具不会Content-Type在上面的转储中显示请求,但这里是来自网络日志.第一张图片显示禁用服务器身份验证时的POST,内容类型正确发送为'application/json'.第二张图片是启用身份验证时,显示OPTIONS请求失败(似乎OPTIONS始终以内容类型'text/plain'?)发送.

@Cornel Masson,你解决了这个问题吗?我不明白为什么你的服务器要求你验证OPTIONS请求,但我面对SAP NetWeaver服务器的同样问题.我已经阅读了整个CORS规范(我推荐),所以我可以向你澄清一些疑问.
关于你的句子
在Angular应用程序中,我明确设置了以下请求标头.AFAIK withCredentials的此设置应确保即使对于OPTIONS请求也会发送凭据:
根据你的判决:
由于内容类型:"application/json",Chrome看起来像是在推出我的所有POST!
如果头字段名称是Accept,Accept-Language或Content-Language的ASCII不区分大小写的匹配,或者如果它是Content-Type和头字段的ASCII不区分大小写的匹配,则称头是简单头值媒体类型(不包括参数)是对application/x-www-form-urlencoded,multipart/form-data或text/plain的ASCII不区分大小写的匹配.
编辑:我刚发现一个有同样问题的人反映了真正的问题,如果你使用与他相同的服务器,你将很幸运,https://evolpin.wordpress.com/2012/10/12/the-cors/
小智 2
同样在这里。我使用 Windows NTLM 身份验证。直到 Chrome 版本 37 为止,它都工作正常。在版本 37、38 上,由于 PUT 和 POST 上的飞行前选项中缺少请求授权标头,因此失败并显示 401(未经授权)。
服务器端是Microsoft Web Api 2.1。我尝试了各种 CORS,包括 Microsoft 的最新 NuGet 包,但均无济于事。
我必须通过发送 GET 请求而不是 POST 来解决 Chrome 上的问题,并在多个请求中破坏相当大的数据,因为 URL 自然有大小限制。
以下是请求/响应标头:
Request URL: http://localhost:8082/api/ConfigurationManagerFeed/
Method: OPTIONS
Status: 401 Unauthorized
Request Headers
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,ru;q=0.6
Access-Control-Request-Headers: accept, content-type
Access-Control-Request-Method: POST
Connection: keep-alive
Host: localhost:8082
Origin: http://localhost:8383
Referer: http://localhost:8383/Application/index.html
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36
X-DevTools-Emulate-Network-Conditions-Client-Id: 49E7FC68-A65C-4318-9292-852946051F27
Response Headers
Cache-Control: private
Content-Length: 6388
Content-Type: text/html; charset=utf-8
Date: Fri, 24 Oct 2014 13:40:07 GMT
Server: Microsoft-IIS/7.5
WWW-Authenticate: Negotiate
NTLM
X-Powered-By: ASP.NET
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
33222 次 |
| 最近记录: |