JSONP
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] } })