域上的文档属性。也就是说,受到请求的URL的域必须与当前Web页面的域相同、相同端口。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。
图5同源请求过程
在一些情况下,我们不可以避免地要地需要从其他域名或服务器中跨域请求数据,但前面提到Ajax只能向同一个域中使用相同端口和协议的URL中发送请求;如果URL与启动请求的页面有任何差别,都会引发安全错误。
跨源策略(CORS):是一个Web浏览器技术规范,它定义了一个方法让Web服务器允许其他域名页面访问它的资源。跨源策略定义了一个方法让浏览器和服务器可以交互决定是否允许跨源请求。
图6跨源请求过程
大家注意到同源请求中我们使用的是JSON格式,但在跨源请求中却是使用JSONP,这时大家可能有点困惑,坦然我刚开始学习的时候也是这样的。
首先我们必须理解JSON和JSONP的区别:JSON是一种数据格式,而JSONP像是通过一个方法名来封装JSON格式;由于浏览器允许跨源请求<script>资源,如我们的HTML页面代码中使用了Google的jQuery库,当我们Web
程序发送跨源请求后,服务器给我们提供响应数据,但服务器无法预知接受JSON数据的方法名,所以我们要提供一个方法名。
Ajax跨源请求
跨域请求数据解决方案主要有如下解决方法:
JSONP方式
表单POST方式
服务器代理
Html5的XDomainRequest
Flash request
在介绍JSONP方式解决跨域请求数据之前,首先我们看看JSONP的定义。
JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过Javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
由于同源策略的限制,XMLHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。
假设
博客园提供一个API接口:http://www.cnblogs.com/hotblogs/json?,供开发者调用获取热门博文。
这里我们可以通过两种方式调用该接口:
1. 用Javascript定义回调函数
其实,通过Javascript定义回调函数调用该接口比较直观,我们只需告诉服务器接收数据的方法名就OK了,比如:
http://www.cnblogs.com/hotblogs/json? callback=myFunction
其中myFunction是我们在页面自定义的函数用来接收服务器回传的数据,myFunction的定义如下:
复制代码 代码如下:
// The call back function.
function myFunction(data) {
// Your code here.
}
2. 使用jQuery的Ajax方法
假设我们想在博客中增加显示浪微博的公共微博信息,我们可以在博客中调用微博提供的API获取跨源数据,接下来,我们将使用jQuery的Ajax方法获取跨域数据。
首先,查看微博API文档找到了公共微博的API接口statuses/public_timeline 获取最新的公共微博消息,它支持JSON或XML格式数据。
参数 | 必选 | 类型及范围 | 说明 |
source | true | string | 申请应用时分配的AppKey,调用接口时候代表应用的唯一身份。(采用OAuth授权方式不需要此参数) |
count | false | int,缺省值20,最大值200 | 每次返回的记录数 |
count | false | int,缺省值20,最大值200 | 每次返回的记录数 |
表2请求参数
上面的请求参数只有source(AppKey)是必须的,所以我们需要向微博申请AppKey,在调用API时,只需把我们的AppKey传递给接口就OK了。
接下来让我们看一下微博数据组成,这里我们使用JSON viewer查看微博的数据组成,具体数据如下:
图7微博JSON数据
通过上图,我们知道微博的数据信息很丰富,它是由一些基础数据类型和复杂数据类型user组成的,接下来我们将使用jQuery实现调用微博接口方法。
首先,我们定义一个全局的对象,它包含三个属性分别是:numWeibo、appendTo和appKey,还有三个方法loadWeib