Nginx系列
- 入门——Nginx系列——配置详解
- 进阶——Nginx系列——负载均衡配置
- 进阶——Nginx系列——解决跨域与接口可用性探测
- 进阶——Nginx系列——缓存解决接口性能问题
- 进阶——Nginx系列——accessLog日志挖掘与恶意IP封禁
- 进阶——Nginx系列——websocket反向代理与资源压缩
文章目录
No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘null’ is therefore not allowed access.
一、Nginx解决跨域问题
1、为什么会出现跨域问题?
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
一句话:浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域
2、什么是跨域
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
当前页面的url | 被请求界面的url | 是否跨域 | 原因 |
---|---|---|---|
http://www.demo.com | http:www.demo.com.index.htm | 否 | 同源(协议、域名、端口号一致) |
http://www.demo.com | https:www.demo.com.index.htm | 跨域 | 协议不一样 |
http://www.demo.com | http:www.baidu.com | 跨域 | 域名不一致 |
http://www.demo.com | http:blog.demo.com | 跨域 | 子域名不一致 |
http://www.demo.com | http:www.demo.com:8888 | 跨域 | 端口号不一致 |
3、限制
- 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
- 无法接触非同源网页的 DOM
- 无法向非同源地址发送 AJAX 请求
4、解決跨域方案
- 设置document.domain解决无法读取非同源网页的 Cookie问题
- 跨文档通信 API:window.postMessage()
- JSONP
- Http响应头配置允许跨域
4.1、后端代码配置
/*
* 导入包:import javax.servlet.http.HttpServletResponse;
* 接口参数中定义:HttpServletResponse response
*/
// 允许跨域访问的域名:若有端口需写全(协议+域名+端口),若没有端口末尾不用加'/'
response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com");
// 允许前端带认证cookie:启用此项后,上面的域名不能为'*',必须指定具体的域名,否则浏览器会提示
response.setHeader("Access-Control-Allow-Credentials", "true");
// 提示OPTIONS预检时,后端需要设置的两个常用自定义头
response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");
4.2、Nginx统一处理跨域
location / {
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header Access-Control-Allow-Methods 'GET,POST,OPTIONS';
#如果预检请求则返回成功,不需要转发到后端
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 200;
}
}
二、Nginx进行接口可用性探测
1、为什么配置?
对于一些已经挂了的服务或者有问题的接口,我们不需要将其暴露给外部的时候就可以使用这个类似于微服务解决方案中的熔断功能,这样的好处就是降低的服务器带宽压力。
2、参数讲解
- max_fails=N 设定Nginx与后端节点通信的尝试失败的次数。失败的尝试次数默认是1,如果设为0就会停止统计尝试次数,认为服务器是一直可用的。
- 在fail_timeout参数定义的时间内,如果失败的次数达到此值,Nginx就这个节点不可用。在下一个fail_timeout时间段到来前,服务器不会再被尝试。
3、具体什么是nginx认为的失败呢?
- 可以通过指令proxy_next_upstream来配置什么是失败的尝试。
- 注意默认配置时,http_404状态不被认为是失败的尝试。
4、具体配置
upstream lbs {
server 192.168.0.106:8080 max_fails=2 fail_timeout=60s ;
server 192.168.0.106:8081 max_fails=2 fail_timeout=60s;
}
location /api/ {
proxy_pass http://lbs;
proxy_next_upstream error timeout http_500 http_503 http_404;
}
注:配置完后保存并且重启Nginx