Web

来源:互联网 发布:李安 知乎 编辑:程序博客网 时间:2024/06/03 20:25

跨域的产生是web安全的范畴,是浏览器安全里同源策略的部分,所谓同源策略,是指协议相同、
域名相同、端口相同,同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。1995年,同源政策由 Netscape 公司引入浏览器。

在这个策略下,web浏览器允许第一个页面的脚本访问第二个页面里的数据,但是也只有在两个页面有相同的源时。源是由URI,主机名,端口号组合而成的。这个策略可以阻止一个页面上的恶意脚本通过页面的DOM对象获得访问另一个页面上敏感信息的权限。

这里写图片描述

  • http://www.app.com/categrory/other.html:同源
  • http://app.com/categrory/other.html:不同源(域名不同)
  • http://zy.www.app.com/categrory/other.html:不同源(域名不同)
  • http://www.app.com:81/categrory/other.html:不同源(端口不同)

同源策略的交互图如下,主要是Origin的问题,所说的同源就是这个意思

这里写图片描述

有这种限制的主要原因就是如果没有同源策略将导致安全风险。假设用户在访问银行网站,并且没有登出。然后他又去了任意的其他网站,刚好这个网站有恶意的js代码,在后台请求银行网站的信息。因为用户目前仍然是银行站点的登陆状态,那么恶意代码就可以在银行站点做任意事情。例如,获取你的最近交易记录,创建一个新的交易等等。因为浏览器可以发送接收银行站点的session cookies,在银行站点域上。访问恶意站点的用户希望他访问的站点没有权限访问银行站点的cookie。当然确实是这样的,js不能直接获取银行站点的session cookie,但是他仍然可以向银行站点发送接收附带银行站点session cookie的请求,本质上就像一个正常用户访问银行站点一样。关于发送的新交易,甚至银行站点的CSRF(跨站请求伪造)防护都无能无力,因为脚本可以轻易的实现正常用户一样的行为。所以如果你需要session或者需要登陆时,所有网站都面临这个问题。如果上例中的银行站点只提供公开数据,你就不能触发任意东西,这样的就不会有危险了,这些就是同源策略防护的。当然,如果两个站点是同一个组织的或者彼此互相信任,那么就没有这种危险了。

当跨域的时候,浏览器的console如下图,Access-Control-Allow-Methods 报错,提示http请求跨域

这里写图片描述

目前,同源策略主要限制以下几类情况:

(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。

主要解决的途径:

jsonp(是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问)

<script type="text/javascript">$.ajax({    url:'http://app.huinonggroup.com/app',    type:'POST', //GET    async:true,    //或false,是否异步    data:{        name:'yang',age:25    },    timeout:5000,    //超时时间    dataType:'jsonp',    //返回的数据格式:json/xml/html/script/jsonp/text    jsonp:'callback',    beforeSend:function(xhr){        console.log(xhr)        console.log('发送前')    },    success:function(data,textStatus,jqXHR){        console.log(data)        console.log(textStatus)        console.log(jqXHR)    },    error:function(xhr,textStatus){        console.log('错误')        console.log(xhr)        console.log(textStatus)    },    complete:function(){        console.log('结束')    }});</script>

H5为了解决这个问题,引入了一个全新的API, 跨文档通信 API(Cross-document messaging)。
这个API为window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源。

var popup = window.open('http://bbb.com', 'title');popup.postMessage('Hello World!', 'http://bbb.com');

postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即”协议 + 域名 + 端口”。也可以设为*,表示不限制域名,向所有窗口发送。

var win = document.getElementsByTagName('iframe')[0].contentWindow;var obj = { name: 'Jack' };// 存入对象win.postMessage(JSON.stringify({key: 'storage', method: 'set', data: obj}), 'http://bbb.com');// 读取对象win.postMessage(JSON.stringify({key: 'storage', method: "get"}), "*");window.onmessage = function(e) {  if (e.origin != 'http://aaa.com') return;  // "Jack"  console.log(JSON.parse(e.data).name);};

服务端设置header头信息(* 可以指定域名访问权限)

 // 指定允许其他域名访问   header('Access-Control-Allow-Origin:*'); // 响应类型   header('Access-Control-Allow-Methods:GET'); // 响应头设置   header('Access-Control-Allow-Headers:x-requested-with,content-type');

最后在说说P3P协议,P3P标准的构想是:Web 站点的隐私策略应该告之访问者该站点所收集的信息类型、信息将提供给哪些人、信息将被保留多少时间及其使用信息的方式,如站点应做诸如 “本网站将监测您所访问的页面以提高站点的使用率”或“本网站将尽可能为您提供更合适的广告”等申明。访问支持P3P网站的用户有权查看站点隐私报告,然 后决定是否接受cookie 或是否使用该网站。

//PHP使用P3P协议header( 'P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"' );
//JS使用P3P协议xmlhttp.setRequestHeader( "P3P" , 'CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"' );

谢谢你的阅读,希望对你有那么一点帮助。

原创粉丝点击