前后端分离的协作开发方式,已经被很多公司采用。若前后端部署在不同的域名下,就会碰到跨域的问题。对于跨域的问题,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';可有可无,这里建议保留,有以下好处:

  1. if ($http_origin ~* ^https?://(www|user)\.test\.com$) {里面的正则表达式可能会很复杂,保留 origin list 可以很直观的知道支持的域名
  2. 若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相关推荐

  1. HTTP 头部字段 Cache Control max-age = 0 和 no-cache 的区别

    禁掉缓存的情况:请求百度首页 开启缓存的情况下: 似乎没有什么变化. 再观察请求的头部字段:cache-control: max-age=0 标头 Cache-Control: max-age=0 暗 ...

  2. 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 ...

  3. 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 ...

  4. [认证授权] 6.Permission Based Access Control

    在前面5篇博客中介绍了OAuth2和OIDC(OpenId Connect),其作用是授权和认证.那么当我们得到OAuth2的Access Token或者OIDC的Id Token之后,我们的资源服务 ...

  5. 关于跨域 Response to preflight request doesn‘t pass access control check

    做项目的时候由于访问了不同的服务器,然后导致了跨域问题,报错情况为: has been blocked by CORS policy: Response to preflight request do ...

  6. SAP Spartacus OCC 请求头部的 Access Token 是如何被添加的

    本文讨论下图这些高亮的 Authorization 头部字段,是如何被用户登录后从 commerce 端请求的 Access Token 填充的: 这些 interceptor 通过 HTTP_INT ...

  7. 使用apache的HttpClient进行http通讯,隐藏的HTTP请求头部字段是如何自动被添加的

    我们用apache的HttpClient这个库消费云端的Restful API时,一般都需要两次HTTP调用,第一次获得某种token,比如获取防止跨域请求伪造攻击Cross-site request ...

  8. 协议簇: Media Access Control(MAC) Frame 解析

    Media Access Control(MAC) Frame 解析 前言 千里之行,始于足下. 因为个人从事网络协议开发,一直想深入的学习一下协议族,从这篇开始,我将开始记录分享我学习到的网络协议相 ...

  9. 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 ...

最新文章

  1. putchar函数的基本格式
  2. 一个线程池中的线程异常了,那么线程池会怎么处理这个线程?
  3. k8s yaml字段说明
  4. Java中的访问限制符
  5. 使用PHP管理SQL
  6. Ivanti罗琦:IT服务管理中“拧紧螺丝”要有门道儿!
  7. [原]ActiveReport6 for net使用(一)
  8. LayaAir destroy 销毁与 removeChild 移除节点
  9. 从头开始学做 canvas 动画引擎
  10. 电脑课学生端密码查看
  11. JavaScript 弹出框(警告框、确认框、提示框)
  12. 中国轨道交通设备行业建设投资规模及十四五产量趋势研究报告2021-2027年版
  13. python把一个文件夹内子文件夹下所有文件复制到指定目录下
  14. 一行代码解决IE浏览器的兼容问题
  15. Java可变类型与不可变类型
  16. ural 1998 The old Padawan
  17. PLC机器人控制器编程笔记
  18. .Net Reflector Version 9.0.1.374
  19. 智能笔记大测评!TheBrain vs 印象笔记,谁能更胜一筹?
  20. Flutter从0到1实现高性能、多功能的富文本编辑器(模块分析篇)

热门文章

  1. 做一个功能比较齐全的小程序商城选择好的系统很重要
  2. 牛客2023年情人节比赛 (c/c++题解)
  3. CentOS7搜狗拼音安装
  4. 设置webview的浏览器标识 User-Agent
  5. 仲辛醇/水体系的界面现象——Lammps与Gromacs计算结果对比
  6. 银行网点服务认证_银行网点服务认证标准
  7. 华为机试【连续出牌数量】
  8. CMDN CLUB第14场:小米与友盟专家详解Android开发:
  9. latex制作三线表
  10. 攻防世界(解密篇Crypto)---混合编码