同源策略:
动态内容(如javascript)只能阅读与之同源的哪些http应答和cookie。同源指的是域名、协议、端口号相同。但是,<script><img><iframe><link>的src属性可以跨域加载资源。
解决同源策略:
1.利用服务器来请求别的服务器的数据。
2.通过iframe来解决
3.src属性引入 像<script src=""></script>
index.html
<script>
var jsonpFunc = function(json){
for(var i in json){
console.info(json(i));
}
}
</script>
<script src="http://abc.com/test?callback=jsonpFunc"></script>
abc.com/test.php
<?php
$jsondata = "{a:'a',b:'b'}";
echo $_GET['callback'].'('.$jsondata.')';
?>
jsonp工作过程
1.首先在客户端定义一个函数,加载js文件并把这个函数名作为参数值传到服务器。
2.服务器拿到函数的名字,用js执行函数的形式打印出来作为返回,服务器生成的数据作为函数参数。
3.客户端会以<script>标签内内容的形式执行服务器的返回,这样在客户端页面里就能以服务器生成的值为入参来执行回调函数了
缺点:
1.不支持post方式。
2.安全漏洞
jsonp如果不加内容过滤措施,会引发安全问题
例如
<script src="abc.com/test?callback=document.getElementByTagName('body')[0].append('<input type="text" />');var a ="></script>
如果给页面加上这么一句,在服务器会执行
echo 'document.getElementByTagName('body')[0].append('<input type="text" />');var a ='.'('.$jsondata.')';
服务器返回的这段语句在客户端以js的形式运行就形成脚本注入了。
防范措施
1.服务端加限制,callback的值只能是a-zA-Z0-9
2.服务端加header。
header('Content-type: text/javascript');
3.过滤尖括号。在服务端做一次urlencode,而在output输出decodeURIComponent(‘#####’)
$callback = urlencode($_GET['callback']); echo "window[decodeURIComponent('{$callback}')]({ret:0,msg:’OK’});"