XMLHttpRequest VS. JSONP

    当我们利用XMLHttpRequest对象从本地服务器获取数据时是可以的。

    假设我们使用的数据格式为JSON(JavaScript Object Notation),并且我们在本地服务器上部署了一个样本数据data.json:

{
"completed_in":0.044,
"max_id":306750251744784385,
"max_id_str":"306750251744784385",
"page":1,
"query":"hfhtml5",
"refresh_url":"?since_id=306750251744784385&q=hfhtml5",
"results":[],
"results_per_page":15,
"since_id":0,
"since_id_str":"0"
}

好了,有了数据,我们试着编写一个简单的页面文件来获取该数据:(该页面文件和data.json位于同一目录下)




	Using Canvas
	
	

	
	


页面确实返回了我们从本地服务器获取的数据,我们对其进行了解析。(我们从XMLHttpRequest对象的属性responseText是json字符串,如果需要将其封装成对象,可以使用JSON.parse方法,如果想将对象字符串化,可以使用parse的对称方法JSON.stringnify。)


现在Web Services很流行,它们可以为我们提供需要的数据,比如实时天气信息,比如公交信息,比如其它用户感兴趣的内容。

好了,Twitter为我们提供了一个数据源URL: http://search.twitter.com/search.json?q=hfhtml5  (有些地方需要。需要的密我)

其实它的内容和data.json文件一样:


现在我们来修改一下页面文件,我们使用外部服务器(相对本地服务器而言)来获取数据:

其实只需要修改open方法的第二个参数url:

		request.open("GET", "http://search.twitter.com/search.json?q=hfhtml5");

重新加载该页面:

咦?页面怎么是空白的。到底怎么回事呢?如果你用的是Google Chrome浏览器的话,可以借助自带的JavaScript控制台(Ctrl+Shift+J)查看哪里出错了。



原因找到了,因为XMLHttpRequest对象不允许跨服务器发送请求,因此该请求被拒绝,外部服务器根本就不知道有请求发送给它。这属于一个跨域安全问题(Cross-Domain Security Issues)。


那么该怎么办呢?既然XMLHttpRequest因为考虑到安全性不允许发送请求到外部服务器,只好寻找其它的办法。

想必大家看过文章标题的都应该猜出,我们可以使用JSONP ( JSON with Padding)。

在讲JSONP之前,先看看几个和JS有关的简单例子:

http://wickedlysmart.com/hfhtml5/chapter6/dog.js 这个URL(无需)返回的是一个JS文件,它的内容很简单,就是

alert("woof");
我们编写一个简单的本地服务器页面来加载该JS文件。




	Using Canvas
	


	
	


在body标签内部添加了一个script标签,该标签的src属性指向了外部服务器的js文件。

访问该页面后:


这说明了什么?说明了通过加载外部服务器的js文件,可以调用本地浏览器的内置对象的方法(比如window.alert方法)


再继续:

http://wickedlysmart.com/hfhtml5/chapter6/dog2.js 该js文件的内容是:

animalSays("dog", "woof");
怎么让该方法被调用呢?我们可以在本地页面创建该函数:




	Using Canvas
	
	

	
	



我们增加了一个自定义函数animalSays,该函数接受两个参数,一个是动物名字,一个是动物叫声,另外我们把script标签的属性也修改成另外一个文件。

试着刷新下页面:


看到效果了吧!


好了,有了以上的基础,我们就可以实现从外部服务器获取我们需要的数据了。

只要在外部服务器中生成json数据格式,然后传递给指定的函数即可。

比如:http://wickedlysmart.com/hfhtml5/chapter6/dog3.js 它的内容是

var animal = { "type": "dog", "sound": "woof" };
animalSays(animal);

我们想要得到该外部服务器上的数据,于是编写了该页面文件:




	Using Canvas
	
	

	
	


这里传递的是animal对象,该对象包含type和sound属性。(记得修改script标签的属性值)

刷新下页面:


哈哈,看到了吧,外部服务器端的数据就这样轻松的获取到了。


有个问题,外部服务器怎么知道我们本地服务器页面的函数名呢?

我们可以通过URL来指定:

http://search.twitter.com/search.json?q=hfhtml5&callback=myCallback

我们可以指定callback的值来告诉外部服务器本地页面的函数名字。


看到没有,该js的函数名就是URL尾部指定的名字


需要注意的是,使用JSONP存在安全问题,除非我们信任这些网站,比如Twitter,Facebook,google,否则请不要轻易加载它们的数据文件。而XMLHttpRequest则比JSONP更加安全,但是访问外部服务器受限。

你可能感兴趣的:(JavaScript,JSONP,XMLHttpRequest,跨域安全问题)