欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Nginx跨域处理

程序员文章站 2022-07-10 19:57:29
...

跨域问题来源于浏览器的同源策略,浏览器为了提高网站的安全性,在发送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的原因,你访问其他网站,它就可以偷偷的查询你的隐私信息,如支付宝余额等。


那么现在为什么要进行跨域处理呢?比如我们在开发过程中因为前后端分离的原因等,还有我们可以去看看淘宝的网站,里面不同的内容可能来自不同的域名下
Nginx跨域处理


常见的跨域解决方案:

  • CORS(跨域资源共享)
  • 使用代理(如Nginx)
  • jsonp
  • iframe

首先我们来看一下CORS解决方案,CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服AJAX只能同源使用的限制。


其过程主要是:在访问过程中发现发生跨域情况时,会携带当前服务器发起询问,询问另一台服务器是否允许被访问,允许才可以执行后续处理。

浏览器在跨源AJAX请求的头信息之中,自动在添加一个Origin字段(本次请求来自哪个源 )。
服务器根据这个值,在许可范围内,则在头信息包含 Access-Control-Allow-Origin 。


我们先来看一看浏览器的请求头是在哪里携带来源网址进行询问的,还是以淘宝为例,我们在淘宝页面向访问另一个域名下的内容,就会在请求头中的Origin中修改当前网址,去询问想要访问的服务器,如下:
Nginx跨域处理

那么我们如何处理该跨域请求呢?其实我们之前在Web的三大组件的简单使用,从web.xml到注解中,就介绍过了,如下图:
Nginx跨域处理

这样我们就可以处理浏览器的跨域请求的,我们可以在网页的响应头中看到,如上述淘宝页面,它就允许了任何其它的服务器进行跨域请求。
Nginx跨域处理


上述是我们在代码中,进行处理的,这里还可以使用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参数配置,浏览器中响应头中也是该配置的值
Nginx跨域处理

至于其他的配置,如if ($request_method = 'OPTIONS') { ...等都是CORS里面更加复杂的请求,会在正式通信之前,可能会要求先发一个HTTP的OPTIONS的请求来询问一下是否允许跨域请求等,称为"预检"请求OPTIONS。

最后至于jsonp和iframe等方法这里和Nginx无关,就不介绍了。

相关标签: Nginx