gpt4 book ai didi

google-chrome - Chrome v37/38 CORS 失败(再次),针对 OPTIONS 预检请求出现 401

转载 作者:行者123 更新时间:2023-12-03 10:29:38 29 4
gpt4 key购买 nike

从 Chrome 版本 37 开始,即使所有 CORS header 都正确设置,如果服务器启用了身份验证,预检的跨域请求也会失败(再次)。这是在 localhost (我的开发电脑)。

你们中的一些人可能知道 Chrome/CORS/auth 错误的历史,尤其是在涉及 HTTPS 时。我的问题不涉及 HTTPS:我有一个来自 localhost:8383 的 AngularJS 应用程序与 localhost:8081 上的 Java (Jetty) 服务器通信已激活 HTTP BASIC 身份验证。 GET 工作正常,但 POST 失败并显示 401:

XMLHttpRequest cannot load http://localhost:8081/cellnostics/rest/patient.
Invalid HTTP status code 401

我之前编写了一个自定义 (Java) CORS 过滤器,用于设置正确的 CORS header ,该过滤器一直工作到 v36。它在 v37 和最新的 v38 (38.0.2125.101 m) 中失败。它在 Internet Explorer 11 (11.0.9600) 和 Opera 12.17 (build 1863) 上仍然可以正常工作。

获取 请求成功,但 发布 失败。由于内容类型:“application/json”,Chrome 似乎正在预检我的所有 POST,并且这是预检的 OPTIONS 请求失败。

在 Angular 应用程序中,我明确设置了以下请求 header 。 AFAIK 此设置适用于 withCredentials应确保即使对于 OPTIONS 请求也发送凭据:
//Enable cross domain calls
$httpProvider.defaults.useXDomain = true;

//Send all requests, even OPTIONS, with credentials
$httpProvider.defaults.withCredentials = true;

下面是请求/响应。可以看到在 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"

有没有人知道我还应该做什么?我确保在测试之前清除 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

因此,即使我明确设置了 withCredentials = true,授权 header 似乎并未随 OPTIONS 预检一起发送。 .

但是,为什么 IE 和 Opera 仍然可以工作? Chrome 在这方面是否更符合标准?为什么它有效,然后从 v37 开始失败?

编辑:Chrome 开发工具不显示 Content-Type上面转储中的请求,但这里是来自网络日志。第一张图片显示禁用服务器身份验证时的 POST,内容类型正确发送为“应用程序/json”。第二张图片是启用身份验证时,显示 OPTIONS 请求失败(似乎 OPTIONS 总是以内容类型“文本/纯文本”发送?)。

CORS POST with NO auth on server
CORS POST with auth enabled on server

最佳答案

@Cornel Masson,你解决问题了吗?我不明白为什么您的服务器要求您对 OPTIONS 请求进行身份验证,但我在 SAP NetWeaver 服务器上遇到了同样的问题。我已经阅读了整个 CORS 规范(我推荐),所以我可以澄清你的一些疑问。

关于你的句子

In the Angular app I explicitly set the following request headers. AFAIK this setting for withCredentials should ensure that credentials are sent even for OPTIONS requests:


  • 根据CORS specification当用户代理(因此,浏览器)预检请求(使用 OPTIONS HTTP 方法的请求)时,它必须排除用户凭据(cookies、HTTP 身份验证...)所以 任何 OPTIONS 请求都不能请求为经过身份验证的 .浏览器将请求经过身份验证的实际请求(具有请求的 HTTP 方法的请求,例如 GET、POST...),而不是预检请求。
  • 因此浏览器不得在 OPTIONS 请求中发送凭据。他们会在实际请求中做。如果你写 withCredentials = true 浏览器应该按照我说的做。

  • 根据你的说法:

    It looks like Chrome is pre-flighting all my POSTs due to the content-type: "application/json":


  • 该规范还表示,当 header 不是“简单 header ”时,浏览器将发出预检请求,这里您有这意味着:

    A header is said to be a simple header if the header field name is an ASCII case-insensitive match for Accept, Accept-Language, or Content-Language or if it is an ASCII case-insensitive match for Content-Type and the header field value media type (excluding parameters) is an ASCII case-insensitive match for application/x-www-form-urlencoded, multipart/form-data, or text/plain.

  • application/json 不包括在内,所以浏览器必须像它一样预检请求。

  • 如果有人找到解决方案,将不胜感激。

    编辑:我刚刚发现一个有同样问题的人反射(reflect)了真正的问题,如果你和他使用相同的服务器,你会很幸运, https://evolpin.wordpress.com/2012/10/12/the-cors/

    关于google-chrome - Chrome v37/38 CORS 失败(再次),针对 OPTIONS 预检请求出现 401,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26296779/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com