同源策略 在浏览器的安全策略中“同源策略”非常如雷贯耳,说的是协议、域名、端口相同则视为同源,域名也可换成IP地址,不同源的页面脚本不能获取对方的数据。 要是想使用XMLHttpRequest或者常规的AJAX请求获取另一个站点的数据,浏览器会告诉你“XXXX is not allowed by Access-Control-Allow-Orign”. 因为同源策略的存在,防止了跨域访问的安全问题,但同时也损失了方便获取资源的便利。
跨域的src属性 世事又非绝对,浏览器还是允许几个元素跨域访问外部资源的,如:<script>,<img>,<iframe>,也就是说,在html元素中拥有src属性的元素是可以跨域访问资源。 通过src属性,img可以引用其它站点或图床的图片,大大降低本站的图片持久。 通过src属性,script可以引用CDN的JS文件,加速了浏览器的脚本文件的下载,跨域的数据获取更加高效和方便。 通过src属性,iframe可以嵌入其它站点的页面,可以让页面的框架和可变内容分离,内容引用较为灵活,方便引用其它站点,虽然现在越来越不建议使用它。 正因为跨域访问的存在,web世界才能更加的精彩。 而JSONP正式利用了script标签的跨域能力。 JSONP 全名JSON with padding 就是通过约定,访问跨域服务器上数据的方法。 这种约定其实就是一个函数定义,并且具备数据参数的定义,由跨域服务器的脚本或动态生成的脚本调用并且传递数据参数。 该函数称之为“跨域回调函数”。 1.一个简单的跨域脚本调用 本地服务器上的一个脚本,直接引用了跨域服务器上的脚本文件。 [AppleScript] 纯文本查看 复制代码 <html>
<head>
<title>test</title>
</head>
<body>
<script src="http://localhost:3001/javascripts/jsonpsrc1.js"></script>
</body>
</html> 跨域服务器上的脚本jsonpsrc1.js alert('hi 我们不是一个域的哦');
运行后,浏览器访问本地服务器上的页面,会弹出alert 2.跨域传递数据 在本地服务器的脚本中,约定一个函数,名为jsonpCallback跨域回调函数交由跨域服务器上的脚本调用。 注意,jsonpCallback跨域回调函数的定义必须是在引用跨域服务器上的脚本之前。 [AppleScript] 纯文本查看 复制代码 <html>
<head>
<title>test</title>
</head>
<body>
<script>
function jsonpCallback(data){
alert(JSON.stringify(data,null,2));
}
</script>
<script src="http://localhost:3001/javascripts/jsonpsrc2.js"></script>
</body>
</html> 跨域服务器上的脚本jsonpsrc2.js,按照约定的跨域回调函数名调用,并传递一个数据对象。 jsonpCallback({ name:'白色的海', age:90});
运行后,浏览器访问本地服务器上的页面,会弹出alert,显示跨域服务器传递过来的数据。 3.动态跨域回调函数 通过上面的2种方法已经基本实现了JSONP的使用,但是还存在一个问题,就是必须要提前约定这个跨域回调函数的名字 。 每次都要按照跨域服务器上的的回调函数名进行定义,极为不便。 那么两个跨域的脚本引用能否不绑定同一个函数名称呢。 可以在本地服务器脚本中任意定义跨域回调函数的名称,将该函数名用过参数请求给跨域服务器,在跨域服务器后台代码上动态拼接生成回调函数的调用字符串并响应给请求方。
|