最新消息:20210917 已从crifan.com换到crifan.org

【已解决】chrome中调用api出错:Failed to load Response for preflight has invalid HTTP status code 403

chrome crifan 5275浏览 0评论

chrome中调试,调用某个api,结果出错:

Failed to load Response for preflight has invalid HTTP status code 403

store.js?adc6:128 OPTIONS http://xxx:port/xmt-web/getUserDetail.do 403 (Forbidden)

(anonymous) @ store.js?adc6:128

localhost/:1 Failed to load http://xxx:port/xmt-web/getUserDetail.do: Response for preflight has invalid HTTP status code 403.

但是postman中却是好的 :

尤其是:

之前运行的是好好的,不知道为何现在却不行了。

chrome Failed to load Response for preflight has invalid HTTP status code 403

Chrome Update 52: Response for preflight has invalid HTTP status code 405 · Issue #111 · pouchdb-community/pouchdb-authentication

angularjs – Response for preflight has invalid HTTP status code 403 on angular post request – Stack Overflow

意思是:

Chrome会在真正发送POST请求时,去预先发送一个OPTIONS的请求

-》正常服务器都是支持的,但是此处要访问的服务器没有支持

-〉所以返回403,出错了。

-》即可办法是:

  • 要么是服务器端,加上OPTIONS的支持

  • 要么是客户端,此处Chrome浏览器中,看看能不能禁止发送OPTIONS,直接发送POST

java – Angular 5: Response for preflight has invalid HTTP status code 403 – Stack Overflow

才知道:

此处对于跨域CORS的请求来说:

所有的浏览器,此处是Chrome,都会发送这个OPTIONS的,然后再发送真正的(此处是POST)请求

Response for preflight has invalid HTTP status code 403 (Angular 4):Angular2

然后去看看,真实的app中, 也是同样现象:

在发送真正的POST之前,发送了OPTIONS,结果服务器返回403,所以出错了。

-》但是很奇怪,为何之前是好的??

XMLHttpRequest cannot load Response for preflight has invalid HTTP status code 404 – ionic – Ionic

更深层的原因是:

如果浏览器发送你添加了Authorization的header,则浏览器,出于安全角度考虑,则就会先发送OPTIONS,而且浏览器的此特性,还无法被禁止掉

chrome CORS OPTIONS 403 如何解决

CORS 跨域 实现思路及相关解决方案 – sloong – 博客园

Spring Cloud 项目出现 Options Forbidden 403 问题解决 – CSDN博客

跨域资源共享(CORS) – 最佳实践| 阿里云

"CORS 介绍

跨域资源共享(Cross-Origin Resource Sharing,简称 CORS),是 HTML5 提供的标准跨域解决方案,具体的CORS规则可以参考 W3C CORS规范。

CORS 是一个由浏览器共同遵循的一套控制策略,通过HTTP的Header来进行交互。浏览器在识别到发起的请求是跨域请求的时候,会将Origin的Header加入HTTP请求发送给服务器,比如上面那个例子,Origin的Header就是www.a.com。服务器端接收到这个请求之后,会根据一定的规则判断是否允许该来源域的请求,如果允许的话,服务器在返回的响应中会附带上Access-Control-Allow-Origin这个Header,内容为www.a.com来表示允许该次跨域访问。如果服务器允许所有的跨域请求的话,将Access-Control-Allow-Origin的Header设置为*即可,浏览器根据是否返回了对应的Header来决定该跨域请求是否成功,如果没有附加对应的Header,浏览器将会拦截该请求。

以上描述的仅仅是简单情况,CORS规范将请求分为两种类型,一种是简单请求,另外一种是带预检的请求。预检机制是一种保护机制,防止资源被本来没有权限的请求修改。浏览器会在发送实际请求之前先发送一个OPTIONS的HTTP请求来判断服务器是否能接受该跨域请求。如果不能接受的话,浏览器会直接阻止接下来实际请求的发生。

只有同时满足以下两个条件才不需要发送预检请求:

* 请求方法是如下之一:

    * GET

    * HEAD

    * POST

* 所有的Header都在如下列表中:

    * Cache-Control

    * Content-Language

    * Content-Type

    * Expires

    * Last-Modified

    * Pragma

预检请求会附带一些关于接下来的请求的信息给服务器,主要有以下几种:

* Origin:请求的源域信息

* Access-Control-Request-Method:接下来的请求类型,如POST、GET等

* Access-Control-Request-Headers:接下来的请求中包含的用户显式设置的Header列表

服务器端收到请求之后,会根据附带的信息来判断是否允许该跨域请求,信息返回同样是通过Header完成的:

* Access-Control-Allow-Origin:允许跨域的Origin列表

* Access-Control-Allow-Methods:允许跨域的方法列表

* Access-Control-Allow-Headers:允许跨域的Header列表

* Access-Control-Expose-Headers:允许暴露给JavaScript代码的Header列表

* Access-Control-Max-Age:最大的浏览器缓存时间,单位s。

浏览器会根据以上的返回信息综合判断是否继续发送实际请求。当然,如果没有这些Header浏览器会直接阻止接下来的请求。

这里需要再次强调的一点是,以上行为都是浏览器自动完成的,用户无需关注这些细节。如果服务器配置正确,那么和正常非跨域请求是一样的。"

但是问题来了:

我此处,之前都是正常工作的,服务器那边也没有改动?为何之前可以,现在却会出现OPTIONS的403?

另外,根据上述解释,我此处:

  • header中只有:

    • Content-Type: application/json

  • 方法是:POST

按道理也应该不会去预检查preflight才对啊???

后来才看到:

跨域资源共享 CORS 详解 – 阮一峰的网络日志

"二、两种请求

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

只要同时满足以下两大条件,就属于简单请求。

(1) 请求方法是以下三种方法之一:

* HEAD

* GET

* POST

(2)HTTP的头信息不超出以下几种字段:

* Accept

* Accept-Language

* Content-Language

* Last-Event-ID

* Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain"

-》看来阿里云的文档,有误。

CORS content-type

ajax – jQuery CORS Content-type OPTIONS – Stack Overflow

Cross-Origin Resource Sharing (CORS) – HTTP | MDN

对应的中文版:

HTTP访问控制(CORS) – HTTP | MDN

"简单请求

某些请求不会触发 CORS 预检请求。本文称这样的请求为“简单请求”,请注意,该术语并不属于 Fetch (其中定义了 CORS)规范。若请求满足所有下述条件,则该请求可视为“简单请求”:

* 使用下列方法之一:

    * GET

    * HEAD

    * POST

* Fetch 规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为:

    * Accept

    * Accept-Language

    * Content-Language

    * Content-Type (需要注意额外的限制)

    * DPR

    * Downlink

    * Save-Data

    * Viewport-Width

    * Width

* Content-Type 的值仅限于下列三者之一:

    * text/plain

    * multipart/form-data

    * application/x-www-form-urlencoded

* 请求中的任意XMLHttpRequestUpload 对象均没有注册任何事件监听器;XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。

* 请求中没有使用 ReadableStream 对象。

预检请求

与前述简单请求不同,“需预检的请求”要求必须首先使用 OPTIONS   方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。"

这才是官网权威的解释。

截至目前,确定是:

真正能,彻底的解决此问题的话,必须去(被访问的)服务器端(对应的api接口中)去加上OPTIONS的支持,然后应该就自动解决此问题了。

【后记 20180626】

后来,还是有问题:

【已解决】reactjs中fetch调用接口出错:TypeError: Failed to fetch

转载请注明:在路上 » 【已解决】chrome中调用api出错:Failed to load Response for preflight has invalid HTTP status code 403

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
95 queries in 0.208 seconds, using 23.31MB memory