【转】JS同源策略

来源:互联网 发布:谷歌软件 编辑:程序博客网 时间:2024/05/02 04:33
在web页面的开发中我们经常会说起脚本的跨域访问的问题,这个问题的始作俑者就是javascript语言安全限制中的同源策略(same-origin policy )所造成的。
同源策略简单的说就是一段脚本只能读取来自于同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议和端口号的组合;
示例:来自http://www.360.cn/a/b.html的js脚本访问下列url的结果和原因
URL结果原因http://www.360.cn/c/d.html成功 http://www.360.cn/d/e/f.html成功 https://www.360.cn/a/c.html失败协议不同http://www.360.cn:81/a/c.html失败端口不同http://www.sina.com.cn/a/b.html 失败主机名不同
 
但是在日常的开发中,我们有时候确实需要跨域的访问,怎么办?下面列举了三种情况分别来解决这个问题:
1.某两个具有相同的一级域名的二级域(如se.360.cn和sd.360.cn)下的页面这间的互相访问
在javascript 1.1版本以后,给document对象引进了一个属性叫domain,通过将这个属性设置成指向同一个域名可以满足上面的需求,例如在se.360.cn中的脚本a.js的开始设置
<javascript>
document.domain=360.cn;
</javascript>
在sd.360.cn中的脚本b.js的开始设置
<javascript>
document.domain=360.cn;
</javascript>
这样在a.js和b.js中就都可以通过获得另外一方的document对象来访问其他内容了。
note: 这个办法需要你能控制两个域中的代码
 
2.完全不同的两个域的访问,如www.360.cn和www.360safe.com的互相访问
这种情况通过javascript语言本身就无法解决了,需要借助<javascript>标签的特性和jsonp协议,在html文档里使用<javascript>标签时有个src属性,这个属性对于url的域名是没有任何限制的,jsonp全名json with padding。
一个简单的做法就是利回调函数:
客户端代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Test Jsonp</title>
<script type="text/javascript">
         function jsonpCallback(result)
         {
alert(result.msg);
         }
     </script>
<script type="text/javascript" src="http://test.com/test.php?jsonp=jsonpCallback"></script>
</head>
<body>
</body>
</html>
 
服务端的代码:
<?php
echo $_GET['jsonp']."({msg:'this is json data'})";
?>  

服务端实际上生成了一段js代码,用于放在客户端的<javascript>标签里执行,通过json的强大特性还可以完成更加复杂的功能;
Note:这个办法也需要你能控制两个域中的代码
 
3.假如你无法控制其中一个域的代码,怎么办?
 
这个时候就只能通过代理的方式来满足需求了,图示如下
http://www.test.com/a.html    ---->  http://www.test.com/b.php   ---->  http://www.other.com/c.html
如果a.html想获得c.html的内容,它首先请求和他同域的b.php页面,b.php中通过服务端请求c.html,然后返回给a.html
原创粉丝点击