zepto源碼研究 - ajax.js($.ajaxJSONP 的分析)

簡要:jsonp是一種服務器和客戶端信息傳遞方式,一般是利用script元素賦值src來發起請求。一般凡是帶有src屬性的元素發起的請求都是可以跨域的。

那么jsonp是如何獲取服務器的數據的呢?

jsonp先將指定的一個函數名作為url后面的參數傳遞到服務器,服務器取得函數名并將要傳遞的數據形成json格式與函數名包裝起來形成腳本傳遞給客戶端執行。

/*** jsonp請求* @param options* @param deferred* @returns {*}*/$.ajaxJSONP = function(options, deferred){//未設置type,就走     ajax     讓參數初始化.//如直接調用ajaxJSONP,type未設置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){//清除超時設置timeout
      clearTimeout(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,是否中斷請求

5:callbackName引用 function(){responseData = arguments},其作用是獲取腳本里面的參數內容,然后以類似ajax的形式返回數據。

6:將options.url最后的callback=?換成callback=callbackName,并賦值給script.src。

7:設置超時處理

$(script).on("load error",function(){.....})中大致內容如下:

1:清除超時設置。2:off()清除掉script綁定的所有事件后清除掉remove()。

3:若e.type == 'error' 或者 responseData為空,觸發ajaxError,否則觸發ajaxSuccess。

4:將原來的callbackName傳入responseData運行。

5:很重要的一步,釋放內存。

?

以下是關于jsonp的服務器與客戶端任務流程圖


?

轉載于:https://www.cnblogs.com/zhutao/p/5841893.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/286379.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/286379.shtml
英文地址,請注明出處:http://en.pswp.cn/news/286379.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言試題十之將兩個兩位數的正整數a b合并形成一個整數放在c中。合并的方式是:將a數的十位和個位數依次放在c的十位和千位上,b數的十位和個位數依次放在c數的個位和百位上。

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、 題目 請編寫函…

Blazor University (27)路由 —— 檢測導航事件

原文鏈接:https://blazor-university.com/routing/detecting-navigation-events/檢測導航事件源代碼[1]從 Blazor 訪問瀏覽器導航是通過 NavigationManager 服務提供的。這可以使用 razor 文件中的 inject 或 CS 文件中的 [Inject] 屬性注入到 Blazor 組件中。Locat…

創建 overlay 網絡 - 每天5分鐘玩轉 Docker 容器技術(50)

上一節我們搭建好實驗環境,配置并運行了consul,今天開始創建 overlay 網絡。 在 host1 中創建 overlay 網絡 ov_net1: -d overlay 指定 driver 為 overaly。 docker network ls 查看當前網絡: 注意到 ov_net1 的 SCOPE 為 global&…

Js+Css 控制iframe內容自動縮放

豎屏橫屏效果<div class"h5box"> <iframe src"http://player.youku.com/embed/XMTI4MjU5OTA3Mg" frameborder"0" width"1280px" height"720px"></iframe> </div><script type"tex…

西北冬日的校園很靜謐,卻不失韻味,因為有我們美好的青春!

冬日的校園&#xff0c;從枯黃的落葉開始。。。 落葉與柵欄情深。 冬日的籃球場上&#xff0c;不乏揮汗如雨的你&#xff0c;因為你是夢想與自由的追逐者&#xff0c;你可以戰勝自己的懶惰。 我們的測量實訓場&#xff0c;英雄的用武之地。 測樁&#xff1a;測量的控制點&#…

ps、top 、free查看用戶資源信息

查看root用戶的進程信息。 運行命令&#xff1a; ps -u root 查看oracle用戶的進程信息。 運行命令&#xff1a; ps -u oracle 若查看現在的資源占用情況&#xff0c;如何呢&#xff1f; 運行命令&#xff1a; top 可以很詳細的查看各個進程的運行情況。 若查看內存使用情…

《iVX 高仿美團APP制作移動端完整項目》02 搜索、搜索提示及類別需求分析思路及制作流程

點擊整個專欄查看其它系列文章 &#xff08;系列文章更新中…&#xff09;&#xff1a;《iVX 高仿美團APP制作移動端完整項目》 項目界面預覽&#xff1a; 一、搜索制作 在上一節中我們完成了標題頭的制作&#xff0c;接下來我們查看如何制作搜索欄以及分類區制作。 首先我…

C語言試題十一之計算并輸出下列多項式值:sn=(1-1/2)+(1/3-1/4)+…+(1/(2n-1)1/2n).

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、 題目 請編寫函…

C#封裝FluentValidation,用了之后通篇還是AbstractValidator,真的看不下去了

講故事前幾天看公司一個新項目使用了FluentValidation&#xff0c;大家都知道FluentValidation是一個非常強大的用于構建強類型驗證規則的 .NET 框架&#xff0c;幫程序員解決了繁瑣的校驗問題&#xff0c;用起來非常爽&#xff0c;但我還是遇到了一件非常不爽的事情,如下代碼所…

用批處理修復 win10 無法升級的問題

win10無法升級&#xff0c;通常的做法是先停止windows update 服務&#xff0c;刪除臨時緩存升級目錄&#xff0c;重新啟動升級服務。 寫成一個批處理文件&#xff0c;直接用管理員身份運行一下就搞定。echo offfor /f "skip3 tokens4" %%i in (sc query wuauserv) d…

http304狀態碼緩存設置問題

當瀏覽器第一次加載資源的時候&#xff0c;返回一般為200&#xff0c;意思是成功獲取資源&#xff0c;并會在瀏覽器的緩存中記錄下max-age&#xff0c;第二次訪問的時候&#xff1a;如果只是用瀏覽器打開&#xff0c;那么瀏覽器會去判斷這個資源在緩存里有沒有&#xff0c;如果…

10.2.0.5啟動enterprise manager

10.2.0.5啟動enterprise manager OEM作為一個實用工具&#xff0c;隨著10g和11g的普及&#xff0c;OEM功能越來越強大&#xff0c;oem也應用越來越廣泛。但是如果是10.2.0.5的版本&#xff0c;并且安裝時間在2010年1月之后&#xff0c;可能會遇到OEM無法啟動的情況&#xff0c;…

【數據結構與算法】多種語言(VB、C、C#、JavaScript)系列數據結構算法經典案例教程合集目錄

文章目錄1. 專欄簡介2. 專欄地址3. 專欄目錄1. 專欄簡介 2. 專欄地址 「 劉一哥與GIS的故事 」之《數據結構與算法》 3. 專欄目錄 【經典回放】多種語言系列數據結構算法&#xff1a;二叉樹&#xff08;JavaScript版&#xff09;【經典回放】多種語言系列數據結構算法&#…

《iVX 高仿美團APP制作移動端完整項目》03 推介信息及推薦商家分析及制作

點擊整個專欄查看其它系列文章 &#xff08;系列文章更新中…&#xff09;&#xff1a;《iVX 高仿美團APP制作移動端完整項目》 項目界面預覽&#xff1a; 一、推薦信息制作 推薦信息與之前的標題下推薦信息制作類似&#xff1a; 此時依舊創建一個行&#xff0c;設置其上下…

C語言試題十二之m個人的成績存放在score數組中,請編寫函數function,它的功能是:將低于平均分的人數作為函數值返回,將低于平均分的分數放在below所指定的數組中。

?作者簡介:大家好我是碼莎拉蒂,CSDN、華為云、阿里云、51CTO博客專家?????? ??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 1、 題目 m個人的成績存放在score數組中,請編寫函…

yum的三種方式

RHEL5中實現各種服務的準備條件&#xff1a;(一)、制作YUM本地源&#xff1a;YUM簡介&#xff1a;YUM是Yellow dog Updater Modified的簡稱&#xff0c;yum是軟件的倉庫&#xff0c;它可以是http或ftp站點&#xff0c;也可以是本地軟件池&#xff0c;但必須包含rpm的header&…

利用百度云盤API上傳文件至百度云盤

一、獲取Access Token示例 1. 請您將以下HTTP請求直接粘貼到瀏覽器地址欄內&#xff0c;并按下回車鍵。 https://openapi.baidu.com/oauth/2.0/authorize?response_typetoken&client_idL6g70tBRRIXLsY0Z3HwKqlRE&redirect_urioob&scopenetdisk 2、執行后&#x…

Docker 容器抓包

背景介紹程序在運行期間出現問題時&#xff0c;通常會通過抓包的方式來分析、定位問題。非容器應用一般可以通過 fiddler、wireshark 等工具進行抓包&#xff0c;那么&#xff0c;運行在容器的應用一般通過什么方式進行抓包呢&#xff1f;容器應用一般可以通過 tcpdump、ngrep …

服務發現與健康監測框架Consul-DNS轉發的應用

關于Consul Consul是一個提供服務注冊與發現&#xff0c;健康監測&#xff0c;Key/Value存儲以及多數據中心存儲的分布式框架。官網地址是https://www.consul.io/&#xff0c;公司初步應用后我們老大覺得這東西有點意思&#xff0c;隨即有了翻譯文檔的想法&#xff0c;由于精力…

【ArcGIS風暴】ArcGIS10.6圖斑橢球面積計算原理與方法

文章目錄 1. 橢球面積計算原理2. ArcGIS計算圖斑橢球面積3. ArcGIS計算圖斑投影平面面積1. 橢球面積計算原理 <