跨域问题详解


一、什么是跨域?

 

浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。跨域访问会访问状态码200但是无法访问,还有其他附带的问题,请求COOKIE无法带上。

比如你从域名为120.258.45 的index.html要访问 156.85.14:8000/getaccess 接口,那么就会有跨域问题。一般尝试跨域访问就会出现No 'Access-Control-Allow-Origin' header is present on the requested resource.' ,类似你可以从谷歌控制台,看到提示:

 

二、为什么要禁止跨域访问

这要涉及到浏览器的同源策略,同源策略限制了不同源之间的资源进行交互,用于隔离潜在的恶意文件的安全机制,并且是浏览器最基本的安全机制(同源:协议、域名、端口均相同,localhost和127.0.0.1也属于跨域)。

如果非同源,同源政策限制三种行为

(1) Cookie、LocalStorage 和 IndexDB 无法读取。

(2) DOM 无法获得。

(3) AJAX 请求不能发送。

对于(1) Cookie、LocalStorage 和 IndexDB 无法读取,如果没有同源策略的限制,假设您进入一个受信网站A,输入了账号密码进行登录,服务器端验证通过后会在响应头中添加Set-Cookie字段,在下次访问时,浏览器就会将cookie附加在http请求头字段Cookie中,服务器就知道您已经登录过,下次你再带着这个cookie时访问受信网站A,服务器便不再验证了,如果在cookie信息还存在的情况下,您不小心访问另一个恶意钓鱼网站B,在您不知情的情况下向受信网站A发起了请求,这就相当于不法钓鱼网站登录了您的账户,可以为所欲为了!

对于(2) DOM 无法获得。又比如一个钓鱼网站,模仿银行网站A(没有了同源策略的限制,钓鱼网站就可以很轻松的网站A的DOM),诱导您输入账户密码信息,你的信息就没了,所以最近12306就是因为类似第三方的访问导致410万用户密码等信息泄漏。

对于(3) AJAX 请求不能发送同源政策规定,AJAX请求只能发给同源的网址,否则就报错。

三、怎么解决跨域问题

详细的同源策略通过前端解决的介绍可以看阮一峰的文章 http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html

除了上述解决方法,服务端解决跨域会用到CORS,CORS是一个W3C标准,全称是"跨域资源共享“。详细的可以见阮一峰的文章 http://www.ruanyifeng.com/blog/2016/04/cors.html

 

Nginx配置实例

实例一:允许example.com的应用在www.example2.com上跨域提取数据

在nginx.conf里找到server项,并在里面添加如下配置

location /{

add_header 'Access-Control-Allow-Origin' 'http://example.com';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
...
}

如果需要允许来自任何域的访问,可以这样配置

add_header Access-Control-Allow-Origin *;

注释如下

第一条指令:授权从example.com的请求(必需)

第二条指令:当该标志为真时,响应于该请求是否可以被暴露(可选)

第三条指令:允许脚本访问的返回头(可选)

第四条指令:指定请求的方法,可以是GET, POST, OPTIONS, PUT, DELETE等(可选)

重启Nginx

$ service nginx reload

测试跨域请求

$ curl -I -X OPTIONS -H ``"Origin: http://example.com"` `http:``//www``.example2.com

成功时,响应头是如下所示

HTTP``/1``.1 200 OK``Server: nginx``Access-Control-Allow-Origin: example.com

实例二:Nginx允许多个域名跨域访问

由于Access-Control-Allow-Origin参数只允许配置单个域名或者 * ,当我们需要允许多个域名跨域访问时可以用以下几种方法来实现。

  • 方法一

如需要允许用户请求来自www.example.com、m.example.com、wap.example.com访问www.example2.com域名时,返回头Access-Control-Allow-Origin,具体配置如下

在nginx.conf里面,找到server项,并在里面添加如下配置

具体其他可看:https://www.cnblogs.com/sunmmi/articles/5956554.html

map $http_origin $corsHost {
  default 0;
  "~http://www.example.com" http://www.example.com;
  "~http://m.example.com" http://m.example.com;
  "~http://wap.example.com" http://wap.example.com;
}

server
{
  listen 80;
  server_name www.example2.com;
  root /usr/share/nginx/html;
  location /
  {
      add_header Access-Control-Allow-Origin $corsHost;
  }
}
 

posted on 2019-01-13 19:32  酒夜狸  阅读(544)  评论(0编辑  收藏  举报

导航