跨域
一,什么是跨域
协议,域名,端口,其中一个不一样,就代表跨域
解决方案:
1,前端:
01,jsonp
02,Hash(url中,#后面的部分,hash变动,页面不会刷新,快通信的原理,search改变页面会刷新,所以不能用来跨域通信)
03,postMessage(H5新增的)参考
04,WebSocket(不受同源策略限制)
例如,域名 a.com 下有一个 a.com/test.html 网页,域名 b.com 下有一个 b.com/data.html 网页和 b.com/alert.js 文件。
引导第一步:简单引用js
编写 b.com/alert.js 如下:
alert(123);
对 a.com/test.html 编写如下代码:
<script type='text/javascript' src='http://b.com/alert.js'></script>
运行 a.com/test.html,结果很明显,就是弹出123
引导第二步:引用js返回数据
将 b.com/alert.js 修改为:
myFn(100);
将 a.com/test.html 修改为:
<script> function myFn ( data ) { alert( data + 'px' ); } </script> <script type='text/javascript' src='http://b.com/alert.js'></script>
运行 a.com/test.html,结果是弹出100px
,这个应该也没有什么疑问。
引导第三步:已经跨域成功!
第二步中,如果data——即100
——是我要跨域在b.com下获取的一个数据,那么咱们这不就是已经实现跨域请求了吗!!!
把这个过程再清晰的捋一遍:
<script>
的src
不符合同源策略;- 我通过给
<script>
的src
赋值一个跨域的文件的网址(可能不是一个js文件),这个文件返回的字符串,浏览器会当作javascript来解析; - 而这段javascript中,就可以包含着我所需要的跨域服务器端的数据;
- 最后,我在本页面定义一个myFn函数用来展示数据,而这段javascript中就可以直接调用myFn函数;
引导第四步:引用html格式
<script>
的src
不一定仅仅指向javascript文件,可以指向任何地址。例如:
将 a.com/test.html 修改为:
<script> function myFn ( data ) { alert( data + 'px' ); } </script> <script type='text/javascript' src='http://b.com/data.html'/>
将 b.com/data.html 编写为:(注意,data.html中就写以下一行代码,多了不写)
myFn(100);
运行 a.com/test.html ,结果依然是100px
,其中,100
就是我们要跨域请求的数据。
引导第五步:动态数据
如果要请求的数据是动态的,那就要在动态页面中编写。那么我们就让 a.com/test.html 去调用一个动态的aspx页面:
<script> function myFn ( data ) { alert( data + 'px' ); } </script> <script type='text/javascript' src='http://b.com/data.aspx?callback=myFn'></script>
大家注意,我们在 src 地址中增加了?callback=myFn
,意思是把显示数据的函数也动态传过去了,而第二步、第四步都是静态的写在被调用的文件中的。至于callback参数后台如何接收,如何使用,请接着看:
在 b.com 下增加一个 b.com/data.aspx 页面,后台代码如下:
protected void Page_Load(object sender, EventArgs e) { if (this.IsPostBack == false) { string callback = ""; if (Request["callback"] != null) { callback = Request["callback"]; //服务器端要返回的数据 string data = "1024"; Response.Write(callback + "(" + data + ")"); } } }
代码很简单,获取callback参数,然后组成一个函数的形式返回。如果b.com/data.aspx?callback=myFn
调用的话,那么返回的就是myFn(1024)
。
返回的数据变成动态的了(“1024”),前端页面用于显示数据的函数也编程了动态的了(“callback=myFn”),但是归根结底,形式还是一样的。
引导第六步:调用封装
a.com/test.html 中,仅仅有一个<script>
静静的躺在那里,执行一次之后,就没有作用了。
而实际情况是,a.com/test.html 中,可能随着用户的操作发生若干次的调用。怎么办?——动态增加呗。
function addScriptTag(src) { var script = document.createElement("script"); script.setAttribute("type", "text/javascript"); script.src = src; document.body.appendChild(script); } function myFn (data) { alert(data + 'px'); } //需要调用时: //addScriptTag('b.com/data.aspx?callback=myFn');
总结
以上层层描述的就是JSONP,你不必去记住它的定义,看明白了上述文字,就全能理解。
重点在于:同源策略 + <script>
的src
不属于同源策略 + 通过<script>
的src指向的文件返回服务器端数据。
未完待续