本文是在瞭解了瀏覽器的同源規則以後,學習了破解這個規則的一個簡單有效的方法->JSONP。主要經過阮一峯老師的 博客學習
因此,1995年NetScape公司(火狐的前身),提出了瀏覽器的同源政策,目的是保護使用網站的用戶的信息安全。那麼何謂同源呢javascript
不過,隨着互聯網的發展,有些時候咱們須要破解同源,因此要先學習一下,古老而有效的JSONP方法。html
<form method="POST" action="/..."></form>
,我不用get請求。<h5>您的帳戶餘額是<span id="amount">200</span></h5> <button id="button">付款1塊錢</button> <form action="/pay" method="post"> <input type="text" name="number" value="1"> <input type="submit" value="付款"> </form>
POST
發起請求。那你這提交完了以後,是否是還要在當前頁面刷新一下,才能看到餘額啊。iframe
,就在當前頁面刷新<form action="/pay" method="post" target="result"> <input type="text" name="number" value="1"> <input type="submit" value="付款"> </form> <iframe name="result" src="about:blank" frameborder="0"></iframe>
有什麼反饋信息都在iframe顯示。java
<h5>您的帳戶餘額是<span id="amount">&&&amount&&&</span></h5> <button id="button">付款1塊錢</button> ... button.addEventListener('click', (e) => { let n = amount.innerText let number = parseInt(n, 10) let newNumber = number - 1 amount.innerText = newNumber }
我用&&&amount&&&
佔位符表示總額,服務器端能夠以下處理node
var amount = fs.readFileSync('./db', 'utf-8') //從db中讀取 string = string.replace('&&&amount&&&', amount) //把佔位的數據換成真的數據 ... response.write(string)
//用圖片發起get請求 let image = document.createElement('img') image.src = '/pay' image.onload = function() { alert('打錢成功') amount.innerText = amount.innerText - 1 } image.onerror = function() { alert('打錢失敗') }
這種也是能夠的,並且也會用提示給用戶,交互性還能夠,不過只能發起GET
請求,哈哈,我就是秀一下黑科技,不多用啦……jquery
//用js腳本發起請求 let script = document.createElement('script') script.src = '/pay' document.body.appendChild(script) script.onerror = function() { alert('failed') } ... //服務器端通常這麼幹 if(path === '/pay') { var amount = fs.readFileSync('./db', 'utf8') var newAmount = amount - 1 fs.writeFileSync('./db', newAmount) response.setHeader('Content-Type', 'application/javascript') response.statusCode = 200 response.write(` amount.innerText = amount.innerText - 1 `) response.end() }
以上是js腳本的大體意思,細節不要深究,明白就行。注意一下,添加script
後,要記得document.body.appendChild(script)
git
script
沒錯,但是你每次都往個人html底部加js,這破壞個人html啊//用js腳本發起請求 let script = document.createElement('script') script.src = '/pay' document.body.appendChild(script) script.onload = function(e) { e.currentTarget.remove() //加載完了,就移除 } script.onerror = function(e) { alert('failed') e.currentTarget.remove() //加載完了,就移除 }
button.addEventListener('click', (e) => { //用js腳本發起請求 let script = document.createElement('script') let functionName = 'wushao' + parseInt((Math.random()*100000), 10) window[functionName] = function (result) { if (result === 'success') { amount.innerText = amount.innerText - 1 } else { } } script.src = 'http://想訪問的另外一個網站:端口號/pay?callback=' + functionName document.body.appendChild(script) script.onload = function(e) { e.currentTarget.remove() } script.onerror = function(e) { alert('failed') e.currentTarget.remove() } })
O(∩_∩)O哈哈~,你讓我給你快點講的……,我給你講講細節吧程序員
?callback=functionName
裏面的functionName就能夠了。 window[functionName] = function (result) { }
在window全局對象上添加functionName
屬性,它的值是一個函數,當服務器端響應回來後,瀏覽器端的寫的函數的參數就是服務器端的success
,咱們就知道個人數據成功了。//服務器端只須要這樣就能夠了,不關心你寫的是什麼函數名字 response.write(` ${query.callback}.call(undefined, 'success') `)
script.onload = function(e) { e.currentTarget.remove() delete window[functionName] } script.onerror = function(e) { alert('failed') e.currentTarget.remove() delete window[functionName] }
$.ajax({ url: "http://想訪問的另外一個網站:端口號/pay", // The name of the callback parameter, as specified by the YQL service jsonp: "callback", // Tell jQuery we're expecting JSONP dataType: "jsonp", // Work with the response success: function (response) { if(response === 'success') { amount.innerText = amount.innerText - 1 } } })
jquery jsonp
具體的代碼連接在============>傳送門github
請求方是一個網站(瀏覽器端),響應方是另外一個網站(服務器端)ajax
?callback=functionName
,通常functionName使用隨機函數構造。2.1 functionName.call(undefined, 'success')
數據庫
2.2 或者直接functionName.('success')
這樣的響應。
functionName.call(undefined, 'success')
或者functionName.('success')
這就是JSONP的原理
答曰:JSONP是動態建立的js腳本,這個方法只能發起GET請求,不能發起POST請求。
其餘請求的話,用AJAX
作嘍☺