JSONP不是什么高大上的東西执泰,簡單地來說:
請求方:frontend.com (瀏覽器)
響應(yīng)房:backend.com (服務(wù)器)
- 請求方創(chuàng)建動態(tài)script,其中標(biāo)簽的src指向響應(yīng)方谐丢,假設(shè)請求方的回調(diào)函數(shù)名稱是renderPayment,我們就需要同時傳一個查詢參數(shù)callbackName=renderPayment給響應(yīng)方
<button id="click">click me</button>
let script = document.createElement("script");
let functionName = 'f' + parseInt(Math.random() * 100000, 10);
window[functionName] = function(result){
console.log(`the result from back end is ${result}!`);
}
script.src = `127.0.0.1:8001/pay?callbackName=${functionName}`
document.body.appendChild(script);
// delete script tag when finish the request
script.onload = function(e){
e.currentTarget.remove();
}
})
當(dāng)然我們可以使用jQuery用更簡潔的代碼實現(xiàn):
$.ajax({
url: '127.0.0.1:8001/pay',
dataType: 'jsonp',
success: function(response){
console.log(`the result from back end is ${response}!`);
}
})
- 響應(yīng)方根據(jù)查詢參數(shù)callbackName咆贬,構(gòu)造類似
xxx.call(undefined, '請求方要的數(shù)據(jù)')
xxx('請求方要的數(shù)據(jù)')
這樣的響應(yīng)
if (path === '/pay'){
let amount = fs.readFileSync('./db', 'utf8')
amount -= 1
fs.writeFileSync('./db', amount)
let callbackName = query.callback
response.setHeader('Content-Type', 'application/javascript')
response.write(`
${callbackName}.call(undefined, 'success')
`)
response.end()
}
- 瀏覽器接收到響應(yīng)后,就會執(zhí)行renderPayment.call(undefined, '請求方要的數(shù)據(jù)')
- 那么請求方就獲得了想要的數(shù)據(jù)并且完成處理
這就是JSONP
下面是一些約定成俗的東西:
- GET請求中的查詢參數(shù)通常為callback
- 回調(diào)函數(shù)名通常為非數(shù)字+隨機數(shù)叠艳,如j48174940
最后記錄一道面試題:為什么JSONP不支持POST請求鸠删?
Answer:
- 因為JSONP是通過動態(tài)創(chuàng)建script標(biāo)簽實現(xiàn)的
- 動態(tài)創(chuàng)建script的時候只能用GET贫导,無法使用POST