Principle and Simple Implementation of JSONP

  • 2021-06-28 08:20:59
  • OfStack

In the era of web2.0, skilled use of ajax was an essential skill for every front-end city attacker.However, due to browser limitations, ajax does not allow cross-domain communication.

JSONP is the mainstream solution for cross-domain communication.

Although in jquery we can call jsonp by setting dataType of $.ajax to jsonp, there is no relationship between the implementation principles of jsonp and ajax.jsonp implements cross-domain requests mainly through script, which can link remote urls.For example:


<script src="http://jsonp.js?callback=xxx"></script>

callback defines a function name, while the remote server passes parameters by calling the specified function and passing in parameters.

Searched a lot of articles on the Internet, their implementation method is too simple, there are still many modifications to be applied in practice. I encapsulated an object here, which can be used in practice directly.


var JSONP = {
// 获取当前时间戳
now: function() {
return (new Date()).getTime();
},
// 获取16位随机数
rand: function() {
return Math.random().toString().substr(2);
},
// 删除节点元素
removeElem: function(elem) {
var parent = elem.parentNode;
if(parent && parent.nodeType !== 11) {
parent.removeChild(elem);
}
},
// url组装
parseData: function(data) {
var ret = "";
if(typeof data === "string") {
ret = data;
}
else if(typeof data === "object") {
for(var key in data) {
ret += "&" + key + "=" + encodeURIComponent(data[key]);
}
}
// 加个时间戳,防止缓存
ret += "&_time=" + this.now();
ret = ret.substr(1);
return ret;
},
getJSON: function(url, data, func) {
// 函数名称
var name;
// 拼装url
url = url + (url.indexOf("?") === -1 ? "?" : "&") + this.parseData(data);
// 检测callback的函数名是否已经定义
var match = /callback=(\w+)/.exec(url);
if(match && match[1]) {
name = match[1];
} else {
// 如果未定义函数名的话随机成1个函数名
// 随机生成的函数名通过时间戳拼16位随机数的方式,重名的概率基本为0
// 如:jsonp_1355750852040_8260732076596469
name = "jsonp_" + this.now() + '_' + this.rand();
// 把callback中的?替换成函数名
url = url.replace("callback=?", "callback="+name);
// 处理?被encode的情况
url = url.replace("callback=%3F", "callback="+name);
}
// 创建1个script元素
var script = document.createElement("script");
script.type = "text/javascript";
// 设置要远程的url
script.src = url;
// 设置id,为了后面可以删除这个元素
script.id = "id_" + name;
// 把传进来的函数重新组装,并把它设置为全局函数,远程就是调用这个函数
window[name] = function(json) {
// 执行这个函数后,要销毁这个函数
window[name] = undefined;
// 获取这个script的元素
var elem = document.getElementById("id_" + name);
// 删除head里面插入的script,这3步都是为了不影响污染整个DOM啊
JSONP.removeElem(elem);
// 执行传入的的函数
func(json);
};
// 在head里面插入script元素
var head = document.getElementsByTagName("head");
if(head && head[0]) {
head[0].appendChild(script);
}
}
};

The implementation process is basically written in the notes, see for yourself.The method invoked is similar to jQuery Basic 1.For example:


var data = {
from: " Beijing ",
count: 27,
output: "json",
callback: "?"
}
JSONP.getJSON("http://api.qunar.com/cdnWebservices.jcp", data, function(json) {console.log(json)});

Of course, that's fine:


JSONP.getJSON("http://api.qunar.com/cdnWebservices.jcp?from= Beijing &count=27&output=json&callback=?", null, function(json) {console.log(json)});

As for the implementation of the server side, it is relatively simple, taking php as an example:


$callback = !empty($_GET['callback']) ? $_GET['callback'] : 'callback';
echo $callback.'( .json_encode( $data ).')';

The similarities and differences between ajax and jsonp are further explained:

1. ajax and jsonp are two technologies that "look" alike in the way they are invoked for the same purpose. They both request an url and then process the data returned by the server. Therefore, the framework of jquery and ext encapsulate jsonp as one form of ajax.

2. ajax and jsonp are essentially different things.The core of ajax is to get non-homepage content through XmlHttpRequest, while the core of jsonp is to add dynamically < script > Label to invoke the js script provided by the server.

3. So in fact, the difference between ajax and jsonp is not whether or not they are cross-domain. ajax can achieve cross-domain through service-side proxy 1, and jsonp itself does not exclude the acquisition of data in the same domain.

4. Also, jsonp is a way or non-mandatory protocol, and like ajax1, it does not have to use the json format to transfer data. Strings work if you want, but this is not conducive to using jsonp to provide public services.

In a word, jsonp is not a special case of ajax, even if giants such as jquery encapsulate jsonp into ajax, it will not change this!

Okay, that's it. Any questions are welcome to discuss.


Related articles: