我的筆記,暫時沒有附帶源代碼,見諒。
第一部分闡述什麼是JSONP,附帶面試題一個。
第二部分是發展歷程,img法,script法,JSONP法。沒有源代碼閱讀會筆記困難,再次見諒。
第三部分隨筆記錄一些基礎知識。javascript
請求方:frank.com 的前端程序員(瀏覽器)
響應方:jack.com 的後端程序員(服務器)html
這就是 JSONP
約定:前端
請問JSONP爲何不能發POST請求?
第一句話: 由於JSONP是經過動態建立script實現的。
第二句話: 動態建立script的時候只能用GET,不能用POSTjava
button.addEventLister('click', (e)=>{
let image = document.creatElement('img')
img.src = '/pay'
image.onload = function(){ // 狀態碼是 200~299 則表示成功
alert('打錢成功')
amount.innerText = amount.innerText - 1
}
image.onerror = function(){ // 狀態碼大於等於 400 則表示失敗
alert('打錢失敗')
}
})
複製代碼
<script>
button.addEventLister('click', (e)=>{
let script = document.creatElement('script')
script.src = '/apy'
// 只這樣作是不行的。必須把下句代碼放在body裏才能夠,不能放在js文件
// 只有把下句代碼放在頁面裏,瀏覽器纔會發請求
document.body.appenChild(script)
script.onerror = function(){
alert('打錢失敗')
}
})
</script>
index.js:
response.write(`amount.innerText = amount.innerText - 1`)
複製代碼
可是每次打錢成功都會建立一個script,html就變的很醜,因此咱們要打錢成功或失敗後刪除這個動態建立的script:node
//只需監聽script的onload和onerror,都刪除這個script便可
script.onload = function(){
e.currentTarget.remove()
}
script.onerror = function(){
alert('打錢失敗')
e.currentTarget.remove()
}
複製代碼
script請求法過程描述:jquery
若用戶點擊了打錢的按鈕,就建立一個script,script的src就是要請求的路徑,而後把script放到頁面裏,這樣瀏
覽器就會去發起這個路徑的get請求;若是get成功了,它首先會執行服務器返回的js的響應,這個響應就是操做頁面局
部的刷新,爲何會把響應當成script執行呢?一是由於咱們設置的response.setHeader就是application/java
script;二是我前端確實把它放在script標籤裏的。執行以後,用戶就看到金額減小了,減小以後咱們就去監聽,
不管成功失敗,都會刪除這個script。
複製代碼
若是A網站的程序員要去調用B網站的JS,就必須對B網站的頁面細節知道的很清楚,不然接口就對不上,這樣耦合太大了!因此咱們要解除耦合!程序員
方法:我調用個函數就好了,我不關內心面是什麼面試
response.write(`amount.innerText = amount.innerText - 1`)
改爲
response.write(`xxx.call(undefined,'打錢成功'`)
同時在A網站JS裏,監聽xxx函數。
複製代碼
這個函數名xxx雙方是怎麼傳遞的呢?ajax
A:script.src='http://B.com/pay?callback=xxx'
B:response.write(`$(query.callback).call(undefined,'打錢成功'`)
複製代碼
代碼細節1: json
請求方:frank.com 的前端程序員(瀏覽器)
響應方:jack.com 的後端程序員(服務器)
這就是 JSONP
約定:
functionName = 'om'+parseInt(Math.random()*100000,10)
window[functionName] = function(result){...}
script.src = 'http://jack.com:8002/pay?callback=' + functionName
複製代碼
JSONP
button.addEventListener('click', (e)=>{
let script = document.createElement('script')
let functionName = 'frank'+ parseInt(Math.random()*10000000 ,10)
window[functionName] = function(){ // 每次請求以前搞出一個隨機的函數
amount.innerText = amount.innerText - 0 - 1
}
script.src = '/pay?callback=' + functionName
document.body.appendChild(script)
script.onload = function(e){ // 狀態碼是 200~299 則表示成功
e.currentTarget.remove()
delete window[functionName] // 請求完了就幹掉這個隨機函數
}
script.onerror = function(e){ // 狀態碼大於等於 400 則表示失敗
e.currentTarget.remove()
delete window[functionName] // 請求完了就幹掉這個隨機函數
}
})
複製代碼
//後端代碼
...
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()
}
複製代碼
button.addEventListener('click', (e)=>{
$.ajax({ // 這個名字跟ajax沒有半毛錢關係,ajax是ajax,jsonp是jsonp
url: "http://jack.com:8002/pay",
dataType: "jsonp",
success: function( response ) {
if(response === 'success'){
amount.innerText = amount.innerText - 1
}
}
})
$.jsonp()
})
複製代碼
請問JSONP爲何不能發POST請求?
第一句話: 由於JSONP是經過動態建立script實現的。
第二句話: 動態建立script的時候只能用GET,不能用POST
response.setHeader('Content-Type', 'text/html');
&&&amount&&&
這是一個特殊的佔位符,總體都是,爲了表示這是個人佔位符,別人別碰。fs
是filesystem
的縮寫,該模塊提供本地文件的讀寫能力,基本上是POSIX文件操做命令的簡單包裝。可是,這個模塊幾乎對全部操做提供異步和同步兩種操做方式,供開發者選擇。 FS講義 FS文檔異步 fs.readFile(文件的路徑, 讀取完成後的回調函數)
同步 fs.readFileSync(文件路徑,'utf8')
fs.readFileSync()的第二個參數能夠是一個表示配置的對象,也能夠是一個表示文本文件編碼的字符串。
默認的配置對象是{ encoding: null, flag: 'r' },即文件編碼默認爲null,讀取模式默認爲r(只讀)。
若是第二個參數不指定編碼(encoding),readFileSync方法返回一個Buffer實例,不然返回的是一個字符串。
Buffer對象是Node處理二進制數據的一個接口,它是Node原生提供的全局對象,能夠直接使用。
buffer文檔:https://javascript.ruanyifeng.com/nodejs/buffer.html
複製代碼
action="URL" 規定當提交表單時向何處發送表單數據。
method="get/post" 規定用於發送 form-data 的 HTTP 方法。
target="" 規定在何處打開 action URL。
複製代碼
value="xxx" 規定input元素的值是xxx