程序员人生 网站导航

js便签笔记(13)――jsonp其实很简单【ajax跨域请求】

栏目:互联网时间:2014-11-18 08:46:06

前两天被问到ajax跨域如何解决,还真被问住了,光知道有个甚么jsonp,迷迷糊糊的没有说上来。抱着有问题必须解决的态度,我看了许多资料,原来如此。。。

为什么1直知道jsonp,但1直迷迷糊糊的不明白呢?――网上那些介绍资料都写的太复杂了!

我是能多简单就多简单,争取让你10分钟看完!

1. 同源策略

ajax之所以需要“跨域”,罪魁罪魁就是阅读器的同源策略。即,1个页面的ajax只能获得这个页面相同源或相同域的数据

如何叫“同源”或“同域”呢?――协议、域名、端口号都必须相同。例如:

http://google.com  和  https://google.com 不同,由于协议不同;

http://localhost:8080  和  http://localhost:1000 不同,由于端口不同;

http://localhost:8080  和  https://google.com 不同,协议、域名、端口号都不同,根本不是1家的。

根据同源策略,我自己做的1个网页 http://localhost:8080/test.html 就没法通过ajax直接获得 http://google.com 的数据。

例如,我用ajax去访问1个不同域的页面,毛病结果是这样的:

 

大家想一想,这样其实也有道理。如果没有同源策略,你我都可以随意通过ajax直接获得其他网站的信息,这还稳定套了。。。我自己做1个搜索界面,搜索时直接用ajax从百度获得数据,那不成了小偷了。。。

但是跨域访问是少不了的,mail.163.com 的网页可能需要从 news.163.com 域下获得新闻信息,那怎样办?――开始我们的跨域之旅(固然用iframe也能够实现)

2. 从“盗链”说起

http://www.wfuyu.com/Internet/的许多网站之间图片相互盗链,A网站网页的img.src直接链接到B网站的图片地址,这是常有的事儿。说到“盗链”,大家第1想到的多是如何去避免盗链,今儿咱不管那个。

你再想一想“盗链”和“同源策略”这两个词之间有甚么关系?――对,矛盾!既然都“同源策略”了,怎样还能“盗链”呢?

世间万物都有矛盾,有矛盾了照样可以和谐共处,其实不1定非要你死我活。

重点:<img>的src(获得图片),<link>的href(获得css),<script>的src(获得javascript)这3个都不符合同源策略,它们可以跨域获得数据。因此,你可以直接从1些cdn上获得jQuery,并且你网站上的图片也随时可能被他人盗用,所有最好加上水印!

而我们今天的主角――jsonp――就是由于<script>的src不符合同源策略而来的

3. JSONP

例如,域名 a.com 下有1个 a.com/test.html 网页,域名 b.com 下有1个 b.com/data.html 网页和 b.com/alert.js 文件。

引导第1步:简单援用js

编写 b.com/alert.js 以下:

alert(123);

对 a.com/test.html 编写以下代码:

<script type='text/javascript' src='http://b.com/alert.js'/>

运行 a.com/test.html,结果很明显,就是弹出 【123】 。

 

引导第2步:援用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'/>

运行 a.com/test.html,结果是弹出【 100px 】,这个应当也没有甚么疑问。

 

引导第3步:已跨域成功!

第2步中,如果data――即100――是我要跨域在b.com下获得的1个数据,那末我们这不就是已实现跨域要求了吗!!!

把这个进程再清晰的捋1遍:

  • <script>的src不符合同源策略;
  • 我通过给<script>的src赋值1个跨域的文件的网址(可能不是1个js文件),这个文件返回的字符串,阅读器会当作javascript来解析;
  • 而这段javascript中,就能够包括着我所需要的跨域http://www.wfuyu.com/server/真个数据;
  • 最后,我在本页面定义1个myFn函数用来展现数据,而这段javascript中就能够直接调用myFn函数;

 

引导第4步:援用html格式

<script>的src不1定仅仅指向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中就写以下1行代码,多了不写)

myFn(100);

运行 a.com/test.html ,结果仍然是【 100px 】

其中,“100”就是我们要跨域要求的数据。

 

引导第5步:动态数据

如果要要求的数据是动态的,那就要在动态页面中编写。

那末我们就让 a.com/test.html 去调用1个动态的aspx页面:

<script> function myFn ( data ) { alert( data + 'px' ); } </script> <script type='text/javascript' src='http://b.com/data.aspx?callback=myFn'/>

大家注意,我们在 src 地址中增加了“?callback=myFn”,意思是把显示数据的函数也动态传过去了,而第2步、第4步都是静态的写在被调用的文件中的。

至于callback参数后台如何接收,如何使用,请接着看:

在 b.com 下增加1个 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"]; //http://www.wfuyu.com/server/端要返回的数据 string data = "1024"; Response.Write(callback + "(" + data + ")"); } } }

代码很简单,获得callback参数,然后组成1个函数的情势返回。如果“b.com/data.aspx?callback=myFn”调用的话,那末返回的就是" myFn(1024) "。

返回的数据变成动态的了(“1024”),前端页面用于显示数据的函数也编程了动态的了(“callback=myFn”),但是归根结柢,情势还是1样的。

 

引导第6步:调用封装

a.com/test.html 中,仅唯一1个<script>静静的躺在那里,履行1次以后,就没有作用了。

而实际情况是,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');

 

4. 总结

以上层层描写的就是JSONP,你没必要去记住它的定义,看明白了上述文字,就全能理解。

重点在于:同源策略 + <script>的src不属于同源策略 + 通过<script>的src指向的文件返回http://www.wfuyu.com/server/端数据

ok,就这些!

-------------------------------------------------------------------------------------------------------------

欢迎关注我的微博。

也欢迎关注我的其他教程:

《从设计到模式》深入理解javascript原型和闭包系列微软petshop4.0源码解读视频》《json2.js源码解读视频

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐