jsonp庫解讀與分析

jsonp是一個經(jīng)典的跨域解決方案,雖然現(xiàn)在使用的很少,但是這種經(jīng)典的解決方案還是應(yīng)該了解下,最近在看github中開源的jsonp庫,跟著源碼加上查閱資料了解了一下jsonp前后端主要的工作,借此來分享一下,有不對的地方大家可以留言指出。

前端需要傳遞的內(nèi)容

  • 訪問的服務(wù)器方法名

  • 返回json前端調(diào)用方法

服務(wù)器需要完成的內(nèi)容

按照前端給的回調(diào)函數(shù)名包裹成字符串返回

解析github的jsonp項目

傳遞參數(shù)

使用這個庫需要傳遞三個參數(shù)

  • url

訪問的服務(wù)器函數(shù)

  • opt

    1. name:本地接受服務(wù)器返回json的函數(shù)名稱的

    2. param、preffix 服務(wù)器解析請求并返回json的函數(shù)名稱與接受服務(wù)器返回json的函數(shù)名稱前綴

    3. timeout 等待服務(wù)器返回結(jié)果的最長時間

  • fn

你希望執(zhí)行的回調(diào)函數(shù)

分析jsonp庫代碼

發(fā)起jsonp請求


        var target = document.getElementsByTagName('script')[0] || document.head;

        script = document.createElement('script');

        script.src = url;

        target.parentNode.insertBefore(script, target);

代碼很簡單就是在本地創(chuàng)建script然后發(fā)起url請求

處理等待最大時間方法


if (timeout) {

            timer = setTimeout(function(){

                cleanup();

                if (fn) fn(new Error('Timeout'));

            }, timeout);

        }

jsonp庫在發(fā)起請求前首先執(zhí)行這部分代碼,當(dāng)在給定的時間內(nèi)這個定時器沒有清楚就會執(zhí)行清理函數(shù),這里這里值得注意的是,如果有回調(diào)函數(shù)也會給回調(diào)函數(shù)拋一個錯誤。

清理函數(shù)

寫通用工具方法,要記得寫清理方法處理不再使用的元素,避免浪費資源


  function cleanup(){

            if (script.parentNode) script.parentNode.removeChild(script);

            window[id] = noop; // 將處理服務(wù)器返回數(shù)據(jù)函數(shù)賦值為空函數(shù)

            if (timer) clearTimeout(timer);

        }

  • 首先清理了發(fā)起jsonp請求的script標簽

  • 接著清理監(jiān)聽等待函數(shù)返回最大時間的定時器

  • 并將本地監(jiān)聽函數(shù)設(shè)置為空函數(shù)。

監(jiān)聽服務(wù)器返回


window[id] = function(data){

            cleanup(); // 不要忘記清理

            if (fn) fn(null, data);

        };

在window對象上監(jiān)聽遠端返回,這個id就是前邊設(shè)置的參數(shù)組裝而成的,這里要注意一下這里不能完了執(zhí)行清理函數(shù),以防資源浪費

服務(wù)器處理部分


 const pathName = url.parse(req.url).pathname; // 獲取訪問服務(wù)器的函數(shù)名稱

        const queryData = qs.parse(req.url.split('?')[1]); // 獲取請求參數(shù)部分

        if (pathName === '/jsonp' && queryData['callback']) {

            res.writeHead(200, {

                'Content-Type': 'application/json;charset=utf-8' // 返回類型為json

            });

            var data = {

                name: 'zhouyijun'

            }

            res.end(queryData.callback + `(${JSON.stringify(data)})`) // 返回值,要記得將json對象轉(zhuǎn)換為字符串

        }

這里代碼比較簡單就是通過url解析參數(shù),分發(fā)給對應(yīng)的處理函數(shù),并且取出終端回調(diào)函數(shù)名稱使用字符串拼接成結(jié)果返回給終端。

jsonp GitHub地址

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容