一、前言
jsonp之前写个ssm项目时,使用到过,但是只是过了一遍,最近学习一些前端的东西,又涉及了这方面的只是,于是准备细细学一下。
二、jsonp的理解
在谈什么是jsonp之前,我们需要知道一个名词:同源策略
同源策略
如果协议,端口(如果指定了一个)和主机对于两个页面是相同的,则两个页面具有相同的源。
下面给出了相对http://store.company.com/dir/page.html同源检测的示例:
http://store.company.com/dir2/other.html 成功 dir2/other.html
http://store.company.com/dir/inner/another.html 成功 dir/inner/another.html
https://store.company.com/secure.html 失败 不同的协议 ( https )
http://store.company.com:81/dir/etc.html 失败 不同的端口 ( 81 )
http://news.company.com/dir/other.html 失败 不同的主机 ( news )
怎样的两个源算是两个不同的源呢?
- ip相同,端口不同
- ip不同,端口相同
-
ip不同,端口不同
注意:ip和端口都相同而后面的路径不同的话是同源
基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。
而在我们使用ajax请求不同源的数据时是不能成功的!!!这也就是跨域问题了。这个时候我们就需要使用jsonp了。
jsonp
谈到jsonp,我们首先要知道它不是一个设计模式,还有就是不是一个语言格式(和json没啥关系)。它只是一种解决跨域请求的方法。就一个例子来更加深刻理解jsonp
三、简单jsonp的例子
<script type="text/javascript">
(function () {
$jsonp('http://api.douban.com/v2/movie/in_theaters',{count:,start:},function (data) {
console.log(data);
})
})();
</script>
首先这个 jsonp名不用管,只是一个函数,用来我们实现跨域请求的,我们可以看第一个参数,是一个豆瓣的api,和我本机肯定不是同源的。正常要想请求到数据肯定是会报错的。而这个 jsonp就是需要我们实现的。
/**
* 手写跨域组件
*/
(function(window, document, undefined) {
var jsonp = function(url, data, callback) {
var cbName = 'my_json_cb_' + Math.random().toString().replace('.', '');
window[cbName] = callback;
//1、将data转换为url字符串
var queryString = url.indexOf('?') == - ? '?' : '&';
for (var key in data) {
queryString += key + '=' + data[key] + '&';
}
queryString += 'callback=' + cbName;
var scriptElement = document.createElement('script');
scriptElement.src = url + queryString;
document.body.appendChild(scriptElement);
};
// 全局使用
window.$jsonp = jsonp;
})(window, document)
这个jsonp函数至少要接受两个参数:分别是url和回调函数,我这里传了三个来限制了获取数据的多少。
可以看出,主要是通过创建一个script标签来实现的。在script的src属性是添加上参数url。不过在添加url之前,我们需要对url做一个处理。也就是将回调函数添加上去。最后,将script添加到body上,页面一初始化就加载数据并且执行这个回调了。这样就解决了跨域请求。
跨域的标签: script、img、iframe、link。不过我们最常用的是script,因为其它几个或多或少都有点小问题或者麻烦。
五、总结
总的来说,就是利用一个可以跨域的标签绕过同源策略来请求数据。