浏览器跨域 Access-Control-Allow-Headers 问题

Access-Control-Allow-Headers

当浏览器发送接口请求出现跨域问题时,目前的做法通常会在接口服务器增加如下配置。

Access-Control-Allow-Origin: *

但是有时也会出现 Access-Control-Allow-Headers 的错误问题。

Access to XMLHttpRequest at'http://www.xxx.com/api' from origin 'http://localhost:8080' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

下面我们就来分析一下原因和解决办法。

原因

浏览器在发送跨域请求并且包含自定义 header 字段时,浏览器会先向服务器发送 OPTIONS 预检请求(preflight request),探测该请求服务是否允许自定义跨域字段。

如果允许,则继续执行 POST、GET请求,否则返回提示错误。

OPTIONS 请求:

Request URL:http://xxx.com/api  
Request Method:OPTIONS  
Status Code:200 OK  
Remote Address:00.00.00.00:80  
Referrer Policy:no-referrer-when-downgrade

Request Header:

Accept:*/*  
Accept-Encoding:gzip, deflate  
Accept-Language:zh-CN,zh;q=0.9,en;q=0.8  
Access-Control-Request-Headers:content-type,xfilecategory,xfilename,xfilesize  
Access-Control-Request-Method:GET  
Connection:keep-alive  
Host:http://localhost:8080/  
Origin:http://localhost:8080/  
User-Agent:Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1

注意⚠️

此时浏览器会向服务器发送预检请求,询问是否支持跨域的自定义 header 字段。设置的 Access-Control-Request-Headers 服务器需要适当的作出应答。

服务器应答方式

服务器需要对 OPTIONS 请求作出应答,通过设置 header 包含 Access-Control-Request-Headers,并且包含 OPTIONS 请求中的 Access-Control-Request-Headers 对值。

例如:

response.setHeader("Access-Control-Allow-Headers", "Content-Type,Access-Token");

另外(其实很重要)

如果你对请求是 simple headers 方式则不会发送预检请求。

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type

当仅包含以上这些请求头(以及满足下面列出的附加要求的值)时,请求不需要在 CORS 的上下文中发送预检请求。

附加要求

CORS 安全标头还必须满足以下要求才能成为 CORS 安全的请求标头:

  • 对于 Accept-LanguageContent-Language:只能存在值 0-9A-Za-z,空间或 *,=.;=
  • 关于 AcceptContent-Type:不能包含 CORS 不安全的请求头字节:"():<>?@[\]{}DeleteTab 和控制字符:0x000x19
  • Content-Type:需要有一个 MIME 类型的值(忽略参数)。可以是 application/x-www-form-urlencodedmultipart/form-datatext/plain 的任意一个。
  • 对于任何 header:值的长度不能大于 128。

通常影响程序发送预检请求的总是 Content-Type 的设置。如果我们在跨域请求时不需要发送预检请求,那么可以通过设置浏览器请求 Content-Typeapplication/x-www-form-urlencodedmultipart/form-datatext/plain 的任意一个来避免。

例如:

headers.set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');

参考

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Allow-Headers https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_request_header https://stackoverflow.com/questions/25727306/request-header-field-access-control-allow-headers-is-not-allowed-by-access-contr

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值