HTTP 头部字段 Access-Control-Allow-Origin
前后端分离的协作开发方式,已经被很多公司采用。若前后端部署在不同的域名下,就会碰到跨域的问题。对于跨域的问题,W3C 有标准的解决方案,即跨域资源共享(Cross-origin resource sharing),缩写为 CORS。详细了解 CORS,可以参考阮一峰的博文:跨域资源共享 CORS 详解。下面介绍一下与跨域相关的 HTTP 响应头部字段:Access-Control-Allow-Origin 。
先看 W3C 对其的说明如下:
The Access-Control-Allow-Origin header indicates whether a resource can be shared based by returning the value of the Origin request header, "*", or "null" in the response. ABNF:
Access-Control-Allow-Origin = "Access-Control-Allow-Origin" ":" origin-list-or-null | "*"
In practice the origin-list-or-null production is more constrained. Rather than allowing a space-separated list of origins, it is either a single origin or the string "null".
上述说明的大致意思:Access-Control-Allow-Origin 的值是请求头 Origin 字段的值、"*"、"null",然后是 ABNF 格式的定义,最后提示,在产品实际中 origin-list-or-null 多用来做限制,它不是一个空格分隔的 origin 列表,而只能是单个 origin 或字符串 "null"。
读懂了上述 W3C 的说明,就知道,为允许多个域名跨域访问,如下配置 Nginx,都不可行。
add_header 'Access-Control-Allow-Origin' 'http://www.test.com http://user.test.com';
add_header 'Access-Control-Allow-Origin' 'http://www.test.com,http://user.test.com';
add_header 'Access-Control-Allow-Origin' 'http://www.test.com|http://user.test.com';
那么,怎么才能允许多域名跨域访问呢?
当然,如下配置 Nginx,肯定可以。事实上,一些互联网公司,就是这么做的,甚至包括知名的互联网公司。
add_header 'Access-Control-Allow-Origin' '*';
使用"*",有人担心有安全问题,比如知乎上的提问。
StackOverflow 有人问到这样的问题,不少人给出了答案。被采用的回答,是针对 Apache 的,使用 .htaccess ,如下:
# ----------------------------------------------------------------------
# Allow loading of external fonts
# ----------------------------------------------------------------------
<FilesMatch "\.(ttf|otf|eot|woff)$"><IfModule mod_headers.c>SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.net|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin</IfModule>
</FilesMatch>
那么,如何配置 Nginx 呢?和 Apache 的配置思路类似,Nginx 配置如下:
# allow origin list
set $allow_origin 'http://www.test.com http://user.test.com';# set single origin
if ($http_origin ~* ^https?://(www|user)\.test\.com$) {set $allow_origin $http_origin;
}add_header 'Access-Control-Allow-Origin' '$allow_origin';
其实上面的set $allow_origin 'http://www.test.com http://user.test.com';
可有可无,这里建议保留,有以下好处:
if ($http_origin ~* ^https?://(www|user)\.test\.com$) {
里面的正则表达式可能会很复杂,保留 origin list 可以很直观的知道支持的域名- 若ajax访问时,请求头的 Origin 字段不在 origin list 中,浏览器的控制台会打出类似如下的错误信息,由此可以知道,服务器支持的 origin list ,便于调试。
XMLHttpRequest cannot load http://www.test.com/. The 'Access-Control-Allow-Origin' header contains multiple values 'http://www.test.com http://user.test.com', but only one is allowed. Origin 'http://junyi.me' is therefore not allowed access.
结合 CORS on Nginx ,写成 Nginx 配置片段 enable-cors.conf ,使用的时候,只需如下这样:
location / {... other config ...include enable-cors.conf;
}
完整的 enable-cors.conf 配置片段如下:
#
# Wide-open CORS config for nginx
## allow origin list
set $allow_origin 'http://www.test.com http://user.test.com';# set single origin
if ($http_origin ~* ^https?://(www|user)\.test\.com$) {set $allow_origin $http_origin;
}if ($request_method = 'OPTIONS') {add_header 'Access-Control-Allow-Origin' '$allow_origin';## Om nom nom cookies#add_header 'Access-Control-Allow-Credentials' 'true';add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';## Custom headers and headers various browsers *should* be OK with but aren't#add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';## Tell client that this pre-flight info is valid for 20 days#add_header 'Access-Control-Max-Age' 1728000;add_header 'Content-Type' 'text/plain charset=UTF-8';add_header 'Content-Length' 0;return 204;
}
if ($request_method = 'POST') {add_header 'Access-Control-Allow-Origin' '$allow_origin';add_header 'Access-Control-Allow-Credentials' 'true';add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {add_header 'Access-Control-Allow-Origin' '$allow_origin';add_header 'Access-Control-Allow-Credentials' 'true';add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
转载于:https://my.oschina.net/junyiz/blog/1627970
HTTP 头部字段 Access-Control-Allow-Origin相关推荐
- HTTP 头部字段 Cache Control max-age = 0 和 no-cache 的区别
禁掉缓存的情况:请求百度首页 开启缓存的情况下: 似乎没有什么变化. 再观察请求的头部字段:cache-control: max-age=0 标头 Cache-Control: max-age=0 暗 ...
- php access control allow origin,js请求跨域问题--Access-Control-Allow-Origin
在前台调试的时候出现XMLHttpRequest cannot load http://www.xx.com/Action/Index.php?Action=11. No 'Access-Contro ...
- Response to preflight request doesn‘t pass access control check: The value of the ‘Access-Control-Al
错误:Response to preflight request doesn't pass access control check: The value of the 'Access-Control ...
- [认证授权] 6.Permission Based Access Control
在前面5篇博客中介绍了OAuth2和OIDC(OpenId Connect),其作用是授权和认证.那么当我们得到OAuth2的Access Token或者OIDC的Id Token之后,我们的资源服务 ...
- 关于跨域 Response to preflight request doesn‘t pass access control check
做项目的时候由于访问了不同的服务器,然后导致了跨域问题,报错情况为: has been blocked by CORS policy: Response to preflight request do ...
- SAP Spartacus OCC 请求头部的 Access Token 是如何被添加的
本文讨论下图这些高亮的 Authorization 头部字段,是如何被用户登录后从 commerce 端请求的 Access Token 填充的: 这些 interceptor 通过 HTTP_INT ...
- 使用apache的HttpClient进行http通讯,隐藏的HTTP请求头部字段是如何自动被添加的
我们用apache的HttpClient这个库消费云端的Restful API时,一般都需要两次HTTP调用,第一次获得某种token,比如获取防止跨域请求伪造攻击Cross-site request ...
- 协议簇: Media Access Control(MAC) Frame 解析
Media Access Control(MAC) Frame 解析 前言 千里之行,始于足下. 因为个人从事网络协议开发,一直想深入的学习一下协议族,从这篇开始,我将开始记录分享我学习到的网络协议相 ...
- GO + React + Axios Response to preflight request doesn't pass access control check: It does not hav
使用Go + Reat 使用 Axios 请求后端, 出现: Access to XMLHttpRequest at 'http://127.0.0.1:20002/v1/user/login' fr ...
最新文章
- putchar函数的基本格式
- 一个线程池中的线程异常了,那么线程池会怎么处理这个线程?
- k8s yaml字段说明
- Java中的访问限制符
- 使用PHP管理SQL
- Ivanti罗琦:IT服务管理中“拧紧螺丝”要有门道儿!
- [原]ActiveReport6 for net使用(一)
- LayaAir destroy 销毁与 removeChild 移除节点
- 从头开始学做 canvas 动画引擎
- 电脑课学生端密码查看
- JavaScript 弹出框(警告框、确认框、提示框)
- 中国轨道交通设备行业建设投资规模及十四五产量趋势研究报告2021-2027年版
- python把一个文件夹内子文件夹下所有文件复制到指定目录下
- 一行代码解决IE浏览器的兼容问题
- Java可变类型与不可变类型
- ural 1998 The old Padawan
- PLC机器人控制器编程笔记
- .Net Reflector Version 9.0.1.374
- 智能笔记大测评!TheBrain vs 印象笔记,谁能更胜一筹?
- Flutter从0到1实现高性能、多功能的富文本编辑器(模块分析篇)