1.瀏覽器的同源策略
- 同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行交互论颅。這是一個用于隔離潛在惡意文件的重要安全機制设江。
2.一個源的定義
如果兩個頁面的協(xié)議,端口和域名都相同,則兩個頁面具有相同的源株依,這就是同源。
http://www.example.com/dir/page.html
這個網(wǎng)址延窜,協(xié)議是http://
恋腕,域名是www.example.com
,端口是80
(默認端口可以省略)逆瑞。它的同源情況如下荠藤。
-
http://www.example.com/dir2/other.html:
同源 -
http://example.com/dir/other.html:
不同源(域名不同) -
http://v2.www.example.com/dir/other.html:
不同源(域名不同) -
http://www.example.com:81/dir/other.html:
不同源(端口不同)
參考文章
- https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
- http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
同源政策規(guī)定,AJAX請求只能發(fā)給同源的網(wǎng)址获高,否則就報錯哈肖。
JSONP實現(xiàn)跨域訪問數(shù)據(jù)
JSONP(JSON with Padding)是JSON的一種“使用模式”
由于同源策略,一般來說位于 server1.example.com
的網(wǎng)頁無法與不是server1.example.com
的服務器溝通念秧,而 HTML
的<script>
元素是一個例外淤井。
ajax請求受同源策略影響,不允許進行跨域請求
而script標簽src屬性中的鏈接卻可以訪問跨域的js腳本摊趾,利用這個特性币狠,服務端不再返回JSON格式的數(shù)據(jù),而是返回一段調(diào)用某個函數(shù)的js代碼砾层,在src中進行了調(diào)用漩绵,這樣實現(xiàn)了跨域。
JSONP是服務器與客戶端跨源通信的常用方法肛炮。最大特點就是簡單適用止吐,老式瀏覽器全部支持宝踪,服務器改造非常小。
JSONP的基本思想是祟印,動態(tài)創(chuàng)建一個<script>
元素肴沫,script元素發(fā)送請求不熟同源政策的限制,只能發(fā)送get請求蕴忆。服務器收到請求后颤芬,將數(shù)據(jù)放在一個指定名字的回調(diào)函數(shù)里傳回來。
<script>//SRL server rendered javascript
button.addEventListener('click', (e) => {
//動態(tài)創(chuàng)建script
var script = document.createElement('script')
let functionName='blog1'+parseInt(Math.random()*100000,10)
//callback
window[functionName]=function(result){
if(result==='success'){
amount.innerText=amount.innerText-1
}else{}
}
//發(fā)送請求
script.src = 'http://feile.com/pay?callback='+functionName
document.body.appendChild(script)
script.onload = function (e) {
// debugger
e.currentTarget.remove()
delete window[functionName]
}
script.onerror = function (e) {
alert('fail')
e.currentTarget.remove()
delete window[functionName]
}
})
</script>
上面的代碼通過動態(tài)創(chuàng)建添加script元素套鹅,向服務器發(fā)送請求站蝠,查詢字符串必須有callback參數(shù),用來指定回調(diào)函數(shù)的名字卓鹿。
response.write(`${query.callback}.call(undefined,'success')`)
服務器收到這個請求以后菱魔,會將數(shù)據(jù)放在回調(diào)函數(shù)的參數(shù)位置返回。這時只要瀏覽器定義了對應的回調(diào)函數(shù)吟孙,該函數(shù)就會立即被調(diào)用澜倦。