湖南公司响应式网站建设价位,泗阳网站定制,长沙seo搜索,青岛个人网站制作简要#xff1a;jsonp是一种服务器和客户端信息传递方式#xff0c;一般是利用script元素赋值src来发起请求。一般凡是带有src属性的元素发起的请求都是可以跨域的。 那么jsonp是如何获取服务器的数据的呢#xff1f; jsonp先将指定的一个函数名作为url后面的参数传递到服务… 简要jsonp是一种服务器和客户端信息传递方式一般是利用script元素赋值src来发起请求。一般凡是带有src属性的元素发起的请求都是可以跨域的。 那么jsonp是如何获取服务器的数据的呢 jsonp先将指定的一个函数名作为url后面的参数传递到服务器服务器取得函数名并将要传递的数据形成json格式与函数名包装起来形成脚本传递给客户端执行。 /*** jsonp请求* param options* param deferred* returns {*}*/$.ajaxJSONP function(options, deferred){//未设置type就走 ajax 让参数初始化.//如直接调用ajaxJSONPtype未设置if (!(type in options)) return $.ajax(options)var _callbackName options.jsonpCallback, //回调函数名//得到最终的回调函数名,callbackName为回调函数名称callbackName ($.isFunction(_callbackName) ?_callbackName() : _callbackName) || (jsonp (jsonpID)), //没有回调赋默认回调script document.createElement(script),originalCallback window[callbackName], //回调函数responseData,//中断请求抛出error事件//这里不一定能中断script的加载但在下面阻止回调函数的执行abort function(errorType) {$(script).triggerHandler(error, errorType || abort)},xhr { abort: abort }, abortTimeout//xhr为只读deferredif (deferred) deferred.promise(xhr)//监听加载完加载出错事件$(script).on(load error, function(e, errorType){//清除超时设置timeoutclearTimeout(abortTimeout)//删除加载用的script。因为已加载完了,.off()清除掉绑定到dom的所有事件$(script).off().remove()//错误调用errorif (e.type error || !responseData) {ajaxError(null, errorType || error, xhr, options, deferred)} else {//成功调用successajaxSuccess(responseData[0], xhr, options, deferred)}//回调函数window[callbackName] originalCallbackif (responseData $.isFunction(originalCallback))originalCallback(responseData[0])//清空闭包引用的变量值不清空需闭包释放父函数才能释放。清空父函数可以直接释放originalCallback responseData undefined})if (ajaxBeforeSend(xhr, options) false) {abort(abort)return xhr}//回调函数设置,给后台执行此全局函数数据塞入window[callbackName] function(){responseData arguments}//回调函数追加到请求地址script.src options.url.replace(/\?(.)\?/, ?$1 callbackName)document.head.appendChild(script)//超时处理通过setTimeout延时处理if (options.timeout 0) abortTimeout setTimeout(function(){abort(timeout)}, options.timeout)return xhr} $.ajaxJSONP(option,deffered) 这个方法在$.ajax中被调用jsonp的请求和异步请求形式很像但jsonp和ajax异步请求要严格去分开jsonp是脚本加载形式。 但在zepto里面jsonp和ajax请求做了形式上的融合都是调用$.ajax方法那么在$.ajax里面针对jsonp请求做出了哪些处理呢 var dataType settings.dataType, hasPlaceholder /\?.\?/.test(settings.url);if (hasPlaceholder) dataType jsonp//不设置缓存加时间戳 _ Date.now()// 当settings.cache null时if (settings.cache false || ((!options || options.cache ! true) (script dataType || jsonp dataType)))//Date.now() 1471504727756settings.url appendQuery(settings.url, _ Date.now())//如果是jsonp,调用$.ajaxJSONP,不走XHR走scriptif (jsonp dataType) {if (!hasPlaceholder) //判断url是否有类似jsonp的参数settings.url appendQuery(settings.url,settings.jsonp ? (settings.jsonp ?) : settings.jsonp false ? : callback?)return $.ajaxJSONP(settings, deferred)} 1首先判断settings.dataType ,如果是jsonp格式则在url后面添加settings.jsonp ?默认添加callback?。然后再调用$.ajaxJSONP方法。但这里为什么不直接调用$.ajaxJSONP而多出一步呢这里会校验url如果url后面有callback?的形式则dataType强制为jsonp。其实这里将hasPlaceholder作为$.ajaxJSONP的第三个参数然后将settings.url的参数的处理放在$.ajaxJSONP内部进行也是可以的。但作者为了能使$.ajaxJSONP重用并符合语义化要求也就默认认定传入其中的settings参数带有callback?的形式。 2对于settings.url做appendQuery处理其实就是保证settings.url后面一定得跟一个形式为callback?的参数如果之前url后面有则不做处理。appendQuery是个工具如果我们有在url后面加入参数的功能的时候用它就可以了。 3调用$.ajaxJSONP 流程总结如下 1获取url参数中的回调函数名callbackName若没有则默认一个。 2将callbackName函数对象保存起来。callbackName将在下面引用一个新的函数。 3创建一个新脚本元素命名为script。 3$(script).on(load error,function(){.....}) 4判断ajaxBeforeSend是否中断请求 5callbackName引用 function(){responseData arguments}其作用是获取脚本里面的参数内容然后以类似ajax的形式返回数据。 6将options.url最后的callback?换成callbackcallbackName并赋值给script.src。 7设置超时处理 $(script).on(load error,function(){.....})中大致内容如下 1清除超时设置。2off()清除掉script绑定的所有事件后清除掉remove()。 3若e.type error 或者 responseData为空触发ajaxError否则触发ajaxSuccess。 4将原来的callbackName传入responseData运行。 5很重要的一步释放内存。 以下是关于jsonp的服务器与客户端任务流程图 转载于:https://www.cnblogs.com/zhutao/p/5841893.html