深入分析jsonp协议原理(2)

$.ajax({ url: 'b.com/b.json', //不同的域 type: 'GET', // jsonp模式只有GET是合法的 dataType: 'jsonp', // 数据类型 jsonp: 'callback', // 指定回调函数名,与服务器端接收的一致,并回传回来 success: function(data) { console.log(data); } })

使用jquery非常方便,那么它是怎么实现这个转化的呢?下面我们来看看这部分的jquery源码。

jq实现jsonp源码分析

我贴出网上给的jquery实现jsonp部分的源码分析:

if (s.dataType == "jsonp") {   // 构建jsonp请求字符集串。jsonp是跨域请求,要加上callback=?后面将会加函数名              if (type == "GET") { //使get的url包含 callback=?后面将 会进行加函数名 if (!s.url.match(jsre))      s.url += (s.url.match(/?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";      } // 构建新的s.data,使其包含 callback=function name else if (!s.data || !s.data.match(jsre))    s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; s.dataType = "json"; } //判断是否为jsonp,如果是 ,进行处理。 if (s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre))) {   jsonp = "jsonp" + jsc ++; //为请 求字符集串的callback=加上生成回调函数名 if (s.data) s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");   s.url = s.url.replace(jsre, "=" + jsonp + "$1"); // 我们需要保证jsonp 类 型响应能正确地执行    //jsonp的类型必须为script。这样才能执行服 务器返回的    //代码。这里就是调用这个回调函数。 s.dataType = "script"; //window下注册一个jsonp回调函数 有,让ajax请求返回的代码调用执行它, window[jsonp] = function(tmp) {    data = tmp; success(); complete();   // 垃圾回收,释放联变量,删除jsonp的对象,除去head中加的script元素   window[jsonp] = undefined;    try {  delete window[jsonp];      } catch (e) {}    if (head)  head.removeChild(script);    };   } if (s.data && type == "GET") {    // data有效,追加到get类型的url上去 s.url += (s.url.match(/?/) ? "&" : "?") + s.data;    // 防止IE会重复发送get和post data s.data = null; } if (s.dataType == "script"  && type == "GET" && parts && (parts[1] && parts[1] != location.protocol || parts[2] != location.host)) {    // 在head中加上<script src=""></script> var head = document.getElementsByTagName("head")[0];    var script = document.createElement("script");    script.src = s.url;    if (s.scriptCharset) script.charset = s.scriptCharset; if (!jsonp) {  //如果datatype不是jsonp,但是url却是跨域 的。采用scriptr的onload或onreadystatechange事件来触发回 调函数。 var done = false; // 对所有浏览器都加上处理器 script.onload = script.onreadystatechange = function() {      if (!done && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) {          done = true;  success();         complete(); head.removeChild(script);        }    };   }   head.appendChild(script); // 已经使用 了script 元素注射来处理所有的事情 return undefined; }

上面的代码稍显复杂,但是我们挑拣重要的看就好了。

我们来分析一下这个过程,其实这个过程也就是上面我提出问题的答案了:

这里执行代码之后,其实就是判断是否配置了dataType: 'jsonp',如果是jsonp协议,则要在url上加callback=jQueryxxx(函数名),jquery会把url转化为:?callback=jQueryxxx,然后再在html中插入,加载完b.json这个文件后,就会执行jQueryxxx这个回调函数,而且此时这个函数里面已经存在了动态数据(json格式数据),所以在页面上执行的时候就能够随心所欲的处理数据了,但是也别忘了后端也要支持jsonp格式才行。所以这样就达到了跨域获取数据的功能。

原生js封装jsonp

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wggwxj.html