摘要:同時請求方在本地定義了這個調(diào)用函數(shù)。如下給調(diào)用函數(shù)創(chuàng)建一個隨機的函數(shù)名為響應(yīng)網(wǎng)站的域名,為響應(yīng)網(wǎng)站的端口號定義函數(shù)執(zhí)行結(jié)束刪除標(biāo)簽執(zhí)行結(jié)束刪除函數(shù)執(zhí)行結(jié)束刪除標(biāo)簽執(zhí)行結(jié)束刪除函數(shù)響應(yīng)方根據(jù)查詢參數(shù)查找到函數(shù)名后,回調(diào)這個函數(shù),做出響應(yīng)。
介紹JSONP之前 ,我們先了解一下,頁面數(shù)據(jù)交互的發(fā)展過程。來看下面一個例子。
付款是我們?nèi)粘V谐R姷囊环N金錢交易,用戶在頁面中點擊付款按鈕,網(wǎng)頁提交請求給服務(wù)器,服務(wù)器收到請求后在數(shù)據(jù)庫對金額進行扣減,然后將消息返回給頁面,告訴用戶給付款成功。
在jsonp ajax的概念實現(xiàn)之前,以上付款的網(wǎng)頁數(shù)據(jù)交互過程是怎么實現(xiàn)的呢?
大家都知道form表單有提交post請求功能,我們可以利用form表單,告訴服務(wù)器【請求扣款】
頁面代碼如下:用表單提交post請求,請求路徑為/pay
Title 您的賬戶余額是&&&amount&&&
服務(wù)器代碼:
當(dāng)請求的路徑為/pay時,數(shù)據(jù)庫進行扣減金額一塊錢,然后給頁面返回success,否則告訴頁面請求出錯了。
else if(path === "/pay"){ var amount = fs.readFileSync("./db","utf8"); var newAmount = amount - 1; fs.writeFileSync("./db",newAmount); response.write("success"); response.end(); } else{ response.statusCode = 404 response.setHeader("Content-Type", "text/html;charset=utf-8") response.write("噢噢,好像出錯了呢") response.end() }
效果如下:
這時候大家會發(fā)現(xiàn)一個問題,每次頁面返回的success后都要再次刷新頁面才能看到賬戶余額,這樣的體驗并不好,這時候神奇的前端程序員們又想到了一個辦法SRJ方案 SRJ - Server Rendered JavaScript。
這時候就不得不佩服前輩們的‘腦洞’啦。程序員想到script標(biāo)簽也可以發(fā)送請求,因此可以通過動態(tài)的創(chuàng)建script標(biāo)簽來向服務(wù)器發(fā)送請求,服務(wù)器完成操作后,返回結(jié)果動態(tài)的修該頁面的賬戶金額;同時本地頁面監(jiān)聽script標(biāo)簽的onload,onerror事件,來刪除動態(tài)創(chuàng)建的script標(biāo)簽,節(jié)省內(nèi)存。
服務(wù)器代碼實現(xiàn)如下:
else if(path === "/pay"){ var amount = fs.readFileSync("./db","utf8"); var newAmount = amount - 1; fs.writeFileSync("./db",newAmount); response.setHeader("Content-Type", "application/javascript") response.statusCode = 200; response.write(`amount.innerText = amount.innerText - 1`); response.end(); } else{ response.statusCode = 404 response.setHeader("Content-Type", "text/html;charset=utf-8") response.write("噢噢,好像出錯了呢") response.end() }
頁面實現(xiàn):
3.JSONP您的賬戶余額是&&&amount&&&
解決了同一網(wǎng)站的信息交互,那么不同的網(wǎng)站之間(不同的域名),數(shù)據(jù)要怎么進行交互呢?以上的SRJ也是可以行得通的,只要修改地址為對方網(wǎng)站地址即可。因為script標(biāo)簽的請求不受域名限制。但是我們發(fā)現(xiàn),如果使用SRJ方案,雙方網(wǎng)站的代碼耦合度太高,為了代碼的解耦,有人提出了JSONP方案:
JSONP(JSON with Padding)是JSON的一種“使用模式”,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題。
1.請求方通過動態(tài)創(chuàng)建的script標(biāo)簽的src路徑指向響應(yīng)方,并且在路徑上添加一個查詢參數(shù)(按照約定,參數(shù)名為callback),該查詢參數(shù)告知響應(yīng)方應(yīng)該調(diào)用的函數(shù)名。同時請求方在本地定義了這個調(diào)用函數(shù)。如下:
let functionName = "tina"+parseInt(Math.random()*100000,10); //給調(diào)用函數(shù)創(chuàng)建一個隨機的函數(shù)名 script.src = "http://u.com:8002/pay?callback=" + functionName; //u.com為響應(yīng)網(wǎng)站的域名,8002為響應(yīng)網(wǎng)站的端口號 window[callback] = function(result){ //定義函數(shù) if(result === "success"){ amount.innerText = amount.innerText - 1; } } script.onload = function(e){ e.currentTarget.remove();//執(zhí)行結(jié)束刪除script標(biāo)簽 delete window[callback]; //執(zhí)行結(jié)束刪除函數(shù) } script.onerror = function (e) { alert("fail"); e.currentTarget.remove();//執(zhí)行結(jié)束刪除script標(biāo)簽 delete window[callback];//執(zhí)行結(jié)束刪除函數(shù) } })
2.響應(yīng)方根據(jù)查詢參數(shù)查找到函數(shù)名后,回調(diào)這個函數(shù),做出響應(yīng)。當(dāng)回調(diào)函數(shù)響應(yīng)的數(shù)據(jù)("success"P)是json格式時以下的代碼就是JSONP。
response.write(`${query.callback}.call(undefinded,"success")`);
3.完成以上步驟后,請求方得到了響應(yīng)的數(shù)據(jù),就會返回到頁面上。
以上代碼是原生JS的實現(xiàn),JQuery也封裝了JSONP,代碼如下
//u.com為響應(yīng)網(wǎng)站的域名,8002為響應(yīng)網(wǎng)站的端口號 $.ajax({ url: "http://u.com:8002/pay", dataType: "jsonp", success: function( response ) { if(response === "success"){ amount.innerText = amount.innerText - 1 } } }) $.jsonp()
這里值得注意一下JQuery封裝的JSONP雖然起了一個與ajax相近的名字,但是與ajax沒有關(guān)系,因為ajax不支持跨域請求。
了解完以上對JSONP的解釋,我們也能很容易明白JSONP為什么不支持POST請求,是因為JSONP是通過動態(tài)創(chuàng)建scipt實現(xiàn)的,并且script標(biāo)簽不支持POST請求。
以上是我個人對JSONP的理解,如有錯誤歡迎指出。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/92527.html
摘要:因為同源策略的限制,我們不能在與外部服務(wù)器進行通信的時候使用。這個是跨域服務(wù)器取數(shù)據(jù)的接口,參數(shù)為回調(diào)函數(shù)的名字,返回的格式為原理首先在客戶端注冊一個然后把的名字傳給服務(wù)器。 一、同源策略 同源策略,它是由Netscape提出的一個著名的安全策略,現(xiàn)在所有的可支持javascript的瀏覽器都會使用這個策略。 為什么需要同源策略,這里舉個例子: 假設(shè)現(xiàn)在沒有同源策略,會發(fā)生什么事...
摘要:是一種協(xié)議,為了解決客戶端請求服務(wù)器跨域的問題,但是并非是正式的傳輸協(xié)議。結(jié)果明明請求回來數(shù)據(jù),結(jié)果還是報錯。是一種使用數(shù)據(jù)的方式,返回的不是對象,是包含對象的腳本。 1、什么是JSONP 一般來說位于 server1.example.com 的網(wǎng)頁無法與不是 server1.example.com的服務(wù)器溝通,而 HTML 的 元素是一個例外。利用 元素的這個開放策略,網(wǎng)頁可以得到...
摘要:因為有同源策略,而在實際開發(fā)中又常常會有跨域的需求,早期開發(fā)者為了解決跨域問題而搞出來這樣一個頗為奇怪的東西。安全早期的瀏覽器處于安全層面的考量,制定同源策略,限制了一個源中加載文本或腳本與來自其它源中資源的交互方式。 AJAX、JSON、JSONP 在 WEB 開發(fā)中,經(jīng)常見到諸如 AJAX、JSON、JSONP 這些名詞。三者看起來很像,很多同學(xué)尤其是沒有系統(tǒng)了解過前端技術(shù)體系的同...