1. 什麼是 JSONP?
是爲了解決兩個網站之間進行交流的問題
通過script標籤來發送請求,因爲script標籤不受域名的限制,而ajax受限制,在末尾加上一段參數來表示要執行的方法
請求方: xujinjun.com 的前端程序員 (瀏覽器)
響應方: jack.com 的後端程序員 (服務器)
- 請求方創建 script,src 指向響應方, 同時傳一個查詢參數 ?callback===yyy
- 響應方根據查詢參數callback, 構造形如
- yyy.call(undefined, '你要的數據')
- yyy('你要的數據')
這樣的響應
- 瀏覽器收到響應,就會執行 yyy.call(undefined, '你要的數據')
- 那麼請求方就知道了他要的數據
yyy 一般是隨機數
2. JSONP 爲什麼不支持 POST
- 因爲jsonp是通過動態創建script來創建的
- 動態創建script的時候只能用get,沒有辦法用post
3. 代碼實現兩網站之間的JSONP請求
server.js (服務器)
if (path === '/') {
var string = fs.readFileSync('./index.html', 'utf8')
var amount = fs.readFileSync('./db', 'utf8')
string = string.replace('&&&amount&&&', amount)
response.setHeader('Content-Type', 'text/html;charset=utf-8')
response.write(string)
response.end()
} else if (path === '/style.css') {
var string = fs.readFileSync('./style.css', 'utf8')
response.setHeader('Content-Type', 'text/css')
response.write(string)
response.end()
} else if (path === '/main.js') {
var string = fs.readFileSync('./main.js', 'utf8')
response.setHeader('Content-Type', 'application/javascript')
response.write(string)
response.end()
} else if (path === '/pay') {
var amount = fs.readFileSync('./db', 'utf8')
var newAmount = amount - 1
if (Math.random() > 0.5) {
fs.writeFileSync('./db', newAmount)
response.setHeader('Content-Type', 'application/javascript')
response.statusCode = 200
response.write(`
${query.callback}.call(undefined, 'success')
`)
response.end()
} else {
response.statusCode = 400
response.write('fail')
}
response.end()
} else {
response.statusCode = 404
response.setHeader('Content-Type', 'text/html;charset=utf-8')
response.write('找不到對應的路徑,你需要自行修改 index.js')
response.end()
}
index.html (瀏覽器)
button.addEventListener('click', (e) => {
let script = document.createElement('script')
let functionName = 'xujinjun' + parseInt(Math.random()*10000, 10)
window[functionName] = function (result) {
if (result === 'success') {
amount.innerText -= 1
} else {
}
}
script.src = 'http://jack.com:8002/pay?callback' + functionName
document.body.appendChild(script)
script.onload = function (e) {
e.currentTarget.remove()
delete window[functionName]
}
script.onerror = function () {
alert('fail')
e.currentTarget.remove()
delete window[functionName]
}
})