Nginx跨域处理
跨域问题来源于浏览器的同源策略,浏览器为了提高网站的安全性,在发送ajax请求时,只有在当前页面地址与请求地址的协议+域名+端口号相同时才允许访问,否则会被拦截。
如:http://www.kami.com/index.html
调用 http://www.kami.com/getInfo
不跨域
-
协议: 即通信协议,比如我们现在常见的http和https,如果当前页面地址使用http协议,请求的地址使用https协议,那么这个请求就存在跨域问题。
如:http://www.kami.com/index.html
调用https://www.kami.com/getInfo
(协议不同:http/https,跨域) -
域名: 即网站网址,如www.baidu.com
如:http://www.kami.com/index.html
调用http://www.kami2.com/getInfo
(主域名不同:kami/kami2,跨域)
如:http://test1.kami.com/index.html
调用http://test2.kami.com/getInfo
(子域名不同:test1/test2,跨域) -
端口号: 即域名对应的服务器的监听端口,这个我们一般是看不到的,因为一般服务器都使用80端口,浏览器默认为80端口,所以不需要在域名后再写出端口号。当8080端口发出的请求为80端口时,也存在跨域。
如:http://www.kami.com:8080/index.html
调用http://www.kami.com:8081/server.php
(端口不同:8080/8081,跨域)
还有就是需要注意的是,比如localhost和127.0.0.1虽然都指向本机,但也属于跨域。
其实就是浏览器不能执行其它网站的脚本,是浏览器施加的安全限制。比如我们写了一个网站,但是没有内容,其内容都是请求百度得到的,然后再填充进我们的网站。更严重的甚至,如果没有跨域限制,因为一些cookie的原因,你访问其他网站,它就可以偷偷的查询你的隐私信息,如支付宝余额等。
那么现在为什么要进行跨域处理呢?比如我们在开发过程中因为前后端分离的原因等,还有我们可以去看看淘宝的网站,里面不同的内容可能来自不同的域名下
常见的跨域解决方案:
- CORS(跨域资源共享)
- 使用代理(如Nginx)
- jsonp
- iframe
首先我们来看一下CORS解决方案,CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服AJAX只能同源使用的限制。
其过程主要是:在访问过程中发现发生跨域情况时,会携带当前服务器发起询问,询问另一台服务器是否允许被访问,允许才可以执行后续处理。
浏览器在跨源AJAX请求的头信息之中,自动在添加一个Origin字段(本次请求来自哪个源 )。
服务器根据这个值,在许可范围内,则在头信息包含 Access-Control-Allow-Origin 。
我们先来看一看浏览器的请求头是在哪里携带来源网址进行询问的,还是以淘宝为例,我们在淘宝页面向访问另一个域名下的内容,就会在请求头中的Origin中修改当前网址,去询问想要访问的服务器,如下:
那么我们如何处理该跨域请求呢?其实我们之前在Web的三大组件的简单使用,从web.xml到注解中,就介绍过了,如下图:
这样我们就可以处理浏览器的跨域请求的,我们可以在网页的响应头中看到,如上述淘宝页面,它就允许了任何其它的服务器进行跨域请求。
上述是我们在代码中,进行处理的,这里还可以使用Nginx进行处理,比如我们设置一个,只有同一个主域名下的才可以访问:
...
server {
listen 80;
server_name www.kami.com;
if ( $http_origin ~ http://(.*).kami.com){
set $allow_url $http_origin;
}
#是否允许请求带有验证信息
add_header Access-Control-Allow-Credentials true;
#允许跨域访问的域名,可以是一个域的列表,也可以是通配符*
add_header Access-Control-Allow-Origin $allow_url;
#允许脚本访问的返回头
add_header Access-Control-Allow-Headers 'x-requested-with,content-type,Cache-Control,Pragma,Date,x-timestamp';
#允许使用的请求方法,以逗号隔开
add_header Access-Control-Allow-Methods 'POST,GET,OPTIONS,PUT,DELETE';
#允许自定义的头部,以逗号隔开,大小写不敏感
add_header Access-Control-Expose-Headers 'WWW-Authenticate,Server-Authorization';
#P3P支持跨域cookie操作
add_header P3P 'policyref="/w3c/p3p.xml", CP="NOI DSP PSAa OUR BUS IND ONL UNI COM NAV INT LOC"';
add_header test 1;
if ($request_method = 'OPTIONS') {
return 204;
}
location / {
root html;
index html html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
其中最重要的就是Access-Control-Allow-Origin参数配置,浏览器中响应头中也是该配置的值
至于其他的配置,如if ($request_method = 'OPTIONS') { ...
等都是CORS里面更加复杂的请求,会在正式通信之前,可能会要求先发一个HTTP的OPTIONS的请求来询问一下是否允许跨域请求等,称为"预检"请求OPTIONS。
最后至于jsonp和iframe等方法这里和Nginx无关,就不介绍了。
上一篇: SpringBoot对静态资源的映射规则
下一篇: SpringBoot对静态资源的映射规则