让你搞懂如何通过Nginx来解决跨域问题
Posted 格格巫 MMQ!!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了让你搞懂如何通过Nginx来解决跨域问题相关的知识,希望对你有一定的参考价值。
nginx跨域实现
首先大家要搞清楚什么是跨域,为什么会有跨域情况的出现。哪些情况属于跨域?
跨域:由于浏览器的同源策略,即属于不同域的页面之间不能相互访问各自的页面内容
注:同源策略,单说来就是同协议,同域名,同端口
URL 说明 是否允许通信
http://www.a.com/a.js
http://www.a.com/b.js 同一域名下 允许
http://www.a.com/lab/a.js
http://www.a.com/script/b.js 同一域名下不同文件夹 允许
http://www.a.com:8000/a.js
http://www.a.com/b.js 同一域名,不同端口 不允许
http://www.a.com/a.js
https://www.a.com/b.js 同一域名,不同协议 不允许
http://www.a.com/a.js
http://70.32.92.74/b.js 域名和域名对应ip 不允许
http://www.a.com/a.js
http://script.a.com/b.js 主域相同,子域不同 不允许
http://www.a.com/a.js
http://a.com/b.js 同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问)
http://www.cnblogs.com/a.js
http://www.a.com/b.js 不同域名 不允许
跨域场景
出于安全考虑(比如csrf攻击),浏览器一般会禁止进行跨域访问,但是因为有时有相应需求,需要允许跨域访问,这时,我们就需要将跨域访问限制打开。
启动一个web服务,端口是8081
然后再开启一个web服务/前端服务都可以。端口是8082,然后再8082的服务中通过ajax来访问8081的服务,这就不满足同源策略,就会出现跨域问题
<%@ page language=“java” contentType=“text/html; charset=utf-8” pageEncoding=“utf-8”%>
Hello World!
![在这里插入图片描述](https://img-blog.csdnimg.cn/027c8dc30f244d6aad3eb069c40ff884.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5qC85qC85berIE1NUSEh,size_20,color_FFFFFF,t_70,g_se,x_16)跨域问题的解决方案
解决跨域问题的方式也有多种。
1、前后端结合(JsonP)
虽然jsonp也可以实现跨域,但是因为jsonp不支持post请求,应用场景受到很大限制,所以这里不对jsonp作介绍。
2、纯后端方式一(CORS方式)
CORS 是w3c标准的方式,通过在web服务器端设置:响应头Access-Cntrol-Alow-Origin 来指定哪些域可以访问本域的数据,ie8&9(XDomainRequest),10+,chrom4,firefox3.5,safair4,opera12支持这种方式。
服务器代理,同源策略只存在浏览器端,通过服务器转发请求可以达到跨域请求的目的,劣势:增加服务器的负担,且访问速度慢。
3.纯后端方式二(Nginx代理方式)【建议这种方式】
首先配置Nginx的反向代理方式
代理访问正常
8082的服务访问Nginx,出现了跨域问题
Nginx配置跨域解决
location /
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods ‘GET, POST, OPTIONS’;
add_header Access-Control-Allow-Headers ‘DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization’;
if ($request_method = 'OPTIONS')
return 204;
proxy_pass http://192.168.12.1:8081;
解决了跨域问题
参数说明
Access-Control-Allow-Origin
服务器默认是不被允许跨域的。给Nginx服务器配置Access-Control-Allow-Origin *后,表示服务器可以接受所有的请求源(Origin),即接受所有跨域的请求。
Access-Control-Allow-Headers
是为了防止出现以下错误:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
这个错误表示当前请求Content-Type的值不被支持。其实是我们发起了"application/json"的类型请求导致的。这里涉及到一个概念:预检请求(preflight request),请看下面"预检请求"的介绍。
Access-Control-Allow-Methods
是为了防止出现以下错误:
Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
给OPTIONS 添加 204的返回
是为了处理在发送POST请求时Nginx依然拒绝访问的错误,发送"预检请求"时,需要用到方法 OPTIONS ,所以服务器需要允许该方法。
预检请求(preflight request)
跨域资源共享(CORS)标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。
其实Content-Type字段的类型为application/json的请求就是上面所说的搭配某些 MIME 类型的 POST 请求,CORS规定,Content-Type不属于以下MIME类型的,都属于预检请求
所以 application/json的请求 会在正式通信之前,增加一次"预检"请求,这次"预检"请求会带上头部信息 Access-Control-Request-Headers: Content-Type:
OPTIONS /api/test HTTP/1.1
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
… 省略了一些
服务器回应时,返回的头部信息如果不包含Access-Control-Allow-Headers: Content-Type则表示不接受非默认的的Content-Type。即出现以下错误:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
以上是关于让你搞懂如何通过Nginx来解决跨域问题的主要内容,如果未能解决你的问题,请参考以下文章