JSONP的诞生
1.首先,因为ajax无法跨域,然后开发者就有所思考
2.其次,开发者发现,script标签的src属性是可以跨域的,把跨域服务器写成 调用本地的函数 ,回调数据回来不就好了?标签的src属性是可以跨域的
3.json刚好被js支持(object)
4.调用跨域服务器上动态生成的js格式文件(不管是什么类型的地址,最终生成的返回值都是一段js代码)
5.这种获取远程数据的方式看起来非常像ajax,但其实并不一样
6.便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP
7.传递一个callback参数给跨域服务端,然后跨域服务端返回数据时会将这个callback参数作为函数名来包裹住json数据即可。
跨域服务器
文件:remote.js
代码:
alert('我是远程文件');
本地
<script type="text/javascript"src="跨域服务器/remote.js"></script>
示例2
跨域服务器
文件:remote.js
代码:
localHandler({"result":"我是远程js带来的数据"});
本地
<script type="text/javascript">
var localHandler=function(data){
alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:'+data.result);
};
<script>
<script type="text/javascript"src="跨域服务器/remote.js"></script>
与AJAX的区别是什么?
ajax和jsonp本质上是不同的东西。标签来调用服务器提供的js脚本。
ajax的核心是通过XmlHttpRequest获取非本页内容
jsonp的核心则是动态添加标签来调用服务器提供的js脚本。
附:
// jsonp 原理
;(function() {
var formatParams = function(data) { //格式化参数
var arr = [];
for (var name in data) {
arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
}
console.info(arr);
return arr.join('&');
}
var jsonp = function(options) {
options = options || {};
if (!options.url || !options.callback) {
throw new Error("参数不合法");
}
//创建 script 标签并加入到页面中
var callbackName = ('jsonp_' + Math.random()).replace(".", "");
var oHead = document.getElementsByTagName('head')[0];
var params = "";
if (options.data) {
options.data[options.callback] = callbackName;
params += formatParams(options.data);
} else {
params += options.callback + "=" + callbackName;
}
var oS = document.createElement('script');
oHead.appendChild(oS);
//创建jsonp回调函数
window[callbackName] = function(json) {
oHead.removeChild(oS);
clearTimeout(oS.timer);
window[callbackName] = null;
options.success && options.success(json);
};
//发送请求
oS.src = options.url + '?' + params;
//超时处理
if (options.time) {
oS.timer = setTimeout(function() {
window[callbackName] = null;
oHead.removeChild(oS);
options.fail && options.fail({
message: "超时"
});
}, options.time);
}
};
window.jsonp = jsonp;
})();
//调用方法
jsonp({
url: "http://localhost:8000/name",
callback: "callback", //跟后台协商的接收回调名
data: {
id: "1000120"
},
success: function(json) {
alert("jsonp_ok");
},
fail: function() {
alert("fail");
},
time: 1000
})