- 介绍
2 准备演示环境
2.1 客户端配置:
上传工具: winscp
以windows 10为例:
配置hosts文件中添加以下内容
192.168.1.16 user.site.com
192.168.1.16 api.site.com
192.168.1.16 shop.site.com
附:
在修改hosts文件时遇到权限问题,可参考下图进行解决。以管理员身份来运行记事本,尔后在记事本---文件---打开---找到hosts文件 ( C:\Windows\System32\drivers\etc )
2.2 服务器配置:
基础环境
操作系统: centos7.2
软件版本: nginx/1.16 PHP 7
软件安装方法: yum
使用的域名: api.site.com user.site.com shop.site.com
附件中演示代码对操作系统、nginx、php版本没有要求,浏览器只要能显示'phpinfo();'页面就能满足我们运行环境的需要。如果已经有PHP环境,确认phpinfo()能够正常显示就可以运行演示代码。
将附件中,“演示代码-本地请求-get_post请求/web-root”目录下的代码,上传到服务器/opt/app/code目录
如果以上配置一切顺利的话,通过浏览器访问http://user.site.com/index.html可以看到如下界面:
3 CORS跨域资源共享
CORS全称是跨域资源共享(Cross-origin resource sharing),在学习CORS跨域之前,先了解一下相关概念,以便我们更好的理解跨域资源共享。
3.1 浏览器的同源策略
同源是指请求的两个URL中的协议、域名、端口三者完全相同。
跨域请求是与浏览器发起请求URL不同源,就是一次跨域请求;
同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能被浏览器进行解析。浏览器同源策略默认阻止“跨域”获取资源。 实际工作场景我们是需要这种“跨域”操作的,这时我们可通过web服务器设置CORS响应头,来解决浏览器同源策略。
跨域只是被浏览器阻止了,跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。
3.2 CORS(跨域资源共享)
CORS是一个W3C标准,全称是跨域资源共享(Cross-origin resource sharing)。CORS是一个机制,它由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应。 通过设置CORS添加HTTP头部信息可以绕过浏览器的同源策略;
3.2.1 CORS请求类型
分为简单请求和非简单请求(预检请求)
简单请求
使用下列方法之一:
GET
HEAD
POST
Content-Type 的值仅限于下列三者之一:
text/plain
multipart/form-data
application/x-www-form-urlencoded
预检请求
触发预检请求可以通过http请求中的PUT、DELETE方法、Content-Type类型不是简单请求中的、自定义http header头部信息; 后续我们会以自定义header头信息进行演示;
3.2.2 HTTP 请求头部字段
- Origin
- Access-Control-Request-Method
- Access-Control-Request-Headers
3.2.3 HTTP 响应头部字段
-
Access-Control-Allow-Origin
Access-Control-Allow-Origin:| *
Access-Control-Allow-Origin: http://user.site.com -
Access-Control-Max-Age
指定了preflight请求的结果能够被缓存多久 - Access-Control-Allow-Credentials
Access-Control-Allow-Credentials: true
是否允许发送cookie信息 -
Access-Control-Allow-Methods
Access-Control-Allow-Methods GET POST 等 - Access-Control-Expose-Headers
是否允许代码获得该字段,如需要应该设置此字段;
4 工作应用场景
4.1 正常请求
确认index.html文件内容url配置如下
var url = "/user.php"; // 请求当前目录下user.php
var url = "/tel.php" ; // 请求当前目录下tel.php
4.2 错误重现和解决
4.2.1 blocked by CORS policy
为满足业务发展的需要,技术人员进行代码优化;所有校验信息由api.site.com完成;
确认index.html文件内容url配置如下
var url = "http://api.site.com/user.php";
var url = http://api.site.com/tel.php;
4.2.2 not ... ... in preflight response
4.3 自定义域名跨域访问
任意子域名跨域访问
多域名跨域访问
4.4 只允许get或post方法
不生效 add_header 'Access-Control-Allow-Methods' 'GET';
nginx设置
只允许GET,但POST请求也可以通过。
add_header 'Access-Control-Allow-Methods' 'GET';
只允许POST,但GET请求也可以通过。
add_header 'Access-Control-Allow-Methods' POST;
简单请求会跳过此选项Access-Control-Allow-Methods ;
5 如何排查问题
5.1 nginx
打开日志的debug模式
5.2 浏览器
调出开发者工具 ,按F12调出、或快捷键 Ctrl + Shift + I 、或网页空白处右键 检查;
5.3 抓包工具wireshark
5.4 tcpdump
tcpdump -i eno16777736 -nnntttvvv host 192.168.1.7 and ! port 22