JSONP是個什麼鬼?

JSONP是個什麼鬼?

來自專欄 余咖咖的技術路

花了一天的時間學習JSONP,總結一下以後方便回顧。在了解什麼是JSONP前,需要先了解什麼是資料庫,如何向伺服器進行請求得到響應,可以用那些方式發送請求?如何向不同的伺服器發送請求並獲得響應?然後推出啥是JSOPN?內容有些長~~

一、資料庫是什麼?

1、文件系統就是一種資料庫:能長久存數據,能夠對內容進行增、刪、改、儲存

2、MySQL是一種資料庫

二、向資料庫做加法

要做的流程如下:

點擊「提交1元錢」發送請求給伺服器,伺服器修改資料庫內容,響應返回所需數據。

用兩種方式來做:圖片請求;script請求;

方案一:用圖片的src向伺服器發送get請求

html代碼如下:

<body> <p>賬戶金額:<span id="amount">!!!amount!!!</span></p> <button id="button">付款1元錢</button> <script> button.addEventListener(click, (e)=>{ let image = document.createElement(img) image.src = /pay image.onload = function(){ // 狀態碼是 200~299 則表示圖片請求成功 alert(成功) } amount.innerText = amount.innerText -1 image.onerror = function(){ // 狀態碼大於等於 400 則表示圖片請求失敗 alert(失敗) } }) </script></body>

其中!!!amount!!!表示一個佔位符,後端通過獲取這個佔位符把資料庫里的內容賦值給它。

解釋:當用戶點擊button按鈕的時候,用圖片發送了路徑為/pay的GET請求給伺服器。伺服器收到後執行下面的代碼,依次是:

1、判斷路徑

2、讀取資料庫的內容,假如是9966。原始數據設置的是10000

3、在最新的內容減1,並保存給變數newAmount

4、把newAmount保存到資料庫,那麼這個時候的值應該為9965

5、確定返回給瀏覽器的內容類型為 image/jpg

6、返回一張圖片

7、結束

伺服器代碼如下:

if(path === /){ let string = fs.readFileSync(./index.html,utf8) let amount = fs.readFileSync(./db.xxx,utf8) //db.xxx文件儲存字元串10000 string = string.replace(!!!amount!!!,amount) response.statusCode = 200 response.setHeader(Content-Type, text/html;charset=utf-8) response.write(string) response.end() }else if(path === /style.css){ let string = fs.readFileSync(./style.css,utf8) response.statusCode = 200 response.setHeader(Content-Type, text/css;charset=utf-8) response.write(string) response.end() }else if(path ===/pay){ let amount = fs.readFileSync(./db.xxx,utf8) var newAmount = amount -1 fs.writeFileSync(./db.xxx,newAmount) response.setHeader(Content-Type, image/jpg) response.write(fs.readFileSync(./1.jpg)) response.end() }else{ response.statusCode = 404 response.setHeader(Content-Type, text/html;charset=utf-8) response.write(嗚嗚嗚) response.end() }

image發送get請求的缺點:得返回一張圖片,同時無法獲取其他的數據內容。

image發送請求所需文件

方案二:用script的src向伺服器發送get請求

html代碼如下:

<body> <p>賬戶金額:<span id="amount">!!!amount!!!</span></p> <button id="button">付款1元錢</button> <script> button.addEventListener(click, (e)=>{ let script = document.createElement(script) script.src = /pay document.body.appendChild(script) //image是不需要插入,但script要插入,記住 script.onload = function(e){ // 狀態碼是 200~299 則表示圖片請求成功 e.currentTarget.remove() //刪除script標籤 alert(成功) } script.onerror = function(){ // 狀態碼大於等於 400 則表示圖片請求失敗 e.currentTarget.remove() //刪除script標籤 alert(失敗) } }) </script></body>

解釋:當用戶點擊button按鈕的時候,用scrip發送了路徑為/pay的GET請求給伺服器。伺服器收到後執行下面的代碼,依次是:

1、判斷路徑

2、讀取資料庫的內容,假如是9966。原始數據設置的是10000

3、在最新的內容減1,並保存給變數newAmount

4、把newAmount保存到資料庫,那麼這個時候的值應該為9965

5、確定返回給瀏覽器的內容類型為 JavaScript

6、返回一段JS代碼,用來更改瀏覽器用戶看到的數字

7、結束

伺服器代碼如下(只有path ===/pay變動):

else if(path ===/pay){ let amount = fs.readFileSync(./db.xxx,utf8) var newAmount = amount -1 fs.writeFileSync(./db.xxx,newAmount) response.setHeader(Content-Type, application/javascript) //返回內容類型為 js response.write(` amount.innerText=amount.innerText-1 `) //返回JS代碼執行,賬戶餘額減1 response.end()}

script請求與image請求相比優劣:不用返回一個圖片,速度回更快一些,同時可以返回其他的內容。但動態創建的script會被執行,響應結束立刻刪除e.currentTarget.remove()

script發送請求所需文件

這種技術就叫做 SRJ - Server Rendered JavaScript

這種技術就叫做 SRJ - Server Rendered JavaScript

這種技術就叫做 SRJ - Server Rendered JavaScript

三、跨域SRJ - JSONP

1、什麼是JSONP(文字解釋)

插一張圖片

2、代碼解釋

html代碼如下:

<body> <p>賬戶金額:<span id="amount">!!!amount!!!</span></p> <button id="button">付款1元錢</button> <script> button.addEventListener(click, (e)=>{ /***以下內容為伺服器獲取參數返回相關值並調用的函數***/ let functionName = frank+parseInt(Math.random()*10000,10) //frank12312423423 window[functionName] = function(result){ if(result === success){ amount.innerText = amount.innerText -1 }else{ } } /******以下內容為動態創建script發送請求,提供參數*********/ let script = document.createElement(script) script.src = http://jack.com:8002/pay?callbackName=+functionName document.body.appendChild(script) //image是不需要插入,但script要插入,記住 script.onload = function(e){ // 狀態碼是 200~299 則表示圖片請求成功 e.currentTarget.remove() //刪除script標籤 delete window[functionName] } script.onerror = function(){ // 狀態碼大於等於 400 則表示圖片請求失敗 e.currentTarget.remove() //刪除script標籤 delete window[functionName] } }) </script></body>

解釋:請求方為frank.com,請求jack.com的伺服器(響應方),通過動態script標籤來請求的。伺服器收到請求後執行:

1、判斷路徑

2、讀取資料庫的內容,假如是9966。原始數據設置的是10000

3、在最新的內容減1,並保存給變數newAmount

4、把newAmount保存到資料庫,那麼這個時候的值應該為9965

5、確定返回給瀏覽器的內容類型為 JavaScript

6、返回內容為:用${query.callbackName}獲取瀏覽器提供的參數yyy,返回請求方所需要的數據,可以是JSONP

7、結束

伺服器代碼如下:

else if(path ===/pay){ let amount = fs.readFileSync(./db.xxx,utf8)//100 var newAmount = amount -1 fs.writeFileSync(./db.xxx,newAmount) response.setHeader(Content-Type, application/javascript) response.write(` ${query.callbackName}.call(undefined,{ "success":true, "left":${newAmount} `}) ) response.end() }

約定:

1、callbackName 必須叫做 callback / jQuery callback

2、funcitonName 為 隨機數 frank12312312312321325()

JSONP跨域請求

3、用jquery來實現JSONP,代碼更加的簡潔

伺服器代碼不變

html代碼如下:

<body> <p>賬戶金額:<span id="amount">!!!amount!!!</span></p> <button id="button">付款1元錢</button <script> button.addEventListener(click, (e)=>{ //這個方法不是ajax,只是一個動態script $.ajax({ url: "http://jack.com:8002/pay", dataType: "jsonp", success: function( response ) { if(response === success){ amount.innerText = amount.innerText - 1 } } }) $.jsonp() }) </script> <script src=https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js></script></body>

解釋:url寫明響應方的路徑;dataType寫明回應的內容類型;當響應成功執行什麼樣的函數;其他複雜的刪減內容jQuery已經做完了。注意這個方法不是ajax,只是一個動態script進行跨域請求,可以叫做JSONP。

四、兩個問題

1、什麼是JSONP

這就是JSONP

2、JSONP為什麼不支持POST請求?

因為JSONP是通過動態創建script來實現的跨域請求的,而script只能發送GET請求。

附上我github代碼地址:

yuyunzhi/JSONP?

github.com圖標
推薦閱讀:

有命令行工具能格式化json嗎?
json 在 Python 爬蟲的應用
這種Json如何使用Gson解析?
使用Json.net處理json
從零開始的 JSON 庫教程(五):解析數組

TAG:JSON | 伺服器 | 資料庫 |