浏览器跨域问题解决方案

一,概述

  1. 为何会出现跨域问题
    同源策略是浏览器安全的基石,首先由NetScape 公司引入浏览器,目前全部浏览器都实行这个政策。同源策略是一种约定,所谓同源策略,指的是浏览器对不一样源的脚本或文本的访问进行限制,例如源A的js 不能读取和设置引入的源的元素属性。只有同协议 同域名 同端口 下才能访问。由于浏览器的同源策略的存在,才有了跨域问题。
  2. 同源策略的限制范围
(1)cookie,LocalStorage,和IndexDB 没法读取

(2)DOM 没法得到

(3)Ajax请求不能发送
  1. 没有同源策略限制的两大危险场景

    (1)没有同源策略限制的接口请求:
    cookie通常用来处理登陆场景,目的是让服务器知道谁发的此次请求。若是你请求接口进行登陆,服务端验证经过后会在响应头加入 Set-Cookie 字段,而后下次再发请求的时候,浏览器会自动将cookie 附加在HTTP请求的头字段Cookie中,服务端就知道这个用户已经登陆过了。问题也就来了,若是你登陆一个银行网站A,而后又进入一个非法网站B,若是没有同源策略,那么非法网站就会获取你登陆A 网站的Cookie,这样一来不发网站就能够登陆你A网站的帐号随心所欲。这就是传说中的 CSRF攻击javascript

    (2)没有同源策略限制的DOM查询:
    最多见的就是钓鱼网站。 有一天你收到一封邮件,说你的银行帐户有风险,干净登陆www.yinghang.com 进行修改,你打开界面发现和你之前登陆的网站如出一辙,而后你输入帐户和密码登录后发现帐户余额正常,就离开了。但是你平时登陆银行帐户的网站是www.yinhang.com。这个钓鱼网站作了什么呢?html

html
<iframe></iframe>

js    
var ifram = window.frames['yinhang'];
var account = iframe.document.getElementById("你输入帐户的输入框")
var pwd     = iframe.document.getElementById("你输入帐户的密码框")

若是没有同源策略限制,你的帐户和密码就会被非网站获取java

二,跨域的解决方案(AJAX)

同源策略规定,AJAX请求只能发给同源的网址,不然就会报错。除了架设服务器代理
(浏览器请求同源服务器,后者再请求外部服务),有三种方法能够解决
  • JSONP
  • Websocket
  • CORS
  1. JSONP

它的思想是,网页经过添加一个<script>元素,向服务器请求JSON数据,这种作法不受同源策略限制。服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
首先,网页动态插入<script>元素,由它向跨源网址发出请求。web

function addScriptTag(src) {
  var script = document.createElement('script');
  script.setAttribute("type","text/javascript");
  script.src = src;
  document.body.appendChild(script);
}

window.onload = function () {
  addScriptTag('http://example.com/ip?callback=foo');
}

function foo(data) {
  console.log('Your public IP address is: ' + data.ip);
};

注意请求的查询字符串有一个callback参数,用来指定回调函数的名字,这是JSONP必须的,服务器收到请求后,会将数据放在回调函数的参数位置返回。跨域

foo({
    "ip":"192.168.1.159"
})

因为<script>元素请求的脚本,直接做为代码运行。这时只要浏览器定义了foo函数,该函数会被当即调用。浏览器

2.WebSocket

WebSocket 是一种通讯协议,使用 ws://(非加密) 和 wss://(加密)做为协议前缀。该协议不实行同源策略,只要服务器支持,就能够经过它进行通讯。安全

var ws = new WebSocket('wss://echo.websocket.org');

      ws.onopen = function (evt) {
          console.log('Connection open ...');
          ws.send('Hello WebSockets!');
      };

      ws.onmessage = function (evt) {
          console.log('Received Message: ', evt.data);
          ws.close();
      };

      ws.onclose = function (evt) {
          console.log('Connection closed.');
      };
3.CORS

CORS 是跨源资源分享(Cross-Origin Resource sharing) 的缩写,它是W3c标准,是跨域AJAX请求的根本解决办法。相比JSONP只能发GET请求,CORS容许任何类型的请求。
CORS须要浏览器和服务器同时支持。目前,全部浏览器都支持该功能,IE浏览器不能低于IE10。服务器

整个CORS通讯过程,都是浏览器自动完成,不须要用户参与。对于开发者来讲,CORS通讯与同源的AJAX通讯没有差异,代码彻底同样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感受。websocket

所以,实现CORS通讯的关键是服务器(服务器端但是判断,让那些域能够请求)。只要服务器实现了CORS接口,
就能够跨源通讯。cookie

相关文章
相关标签/搜索