同源策略與CORS跨域
PS:這篇文章是緊接着JSONP原理和Ajax學習與理解寫的,有些內容是承接了上兩篇文章. 這篇文章只算是我的個人學習筆記,內容沒有經過精心排版,也沒有認真校對格式,一些錯誤請見諒.
用 form , a,img,link,script.都可以跨域發送請求 但是! 同源策略:只有 協議+端口+域名 一模一樣才允許發 AJAX 請求. 例如我們向baidu.com發送Ajax一個請求
請求成功了,但是報了一個錯
加載失敗了, 所以,請求發送出去了,但是拿不到響應!
同源策略
只有 協議+端口+域名 一模一樣才允許發 AJAX 請求
一模一樣一模一樣一模一樣一模一樣一模一樣一模一樣一模一樣一模一樣
http://baidu.com 可以向 http://www.baidu.com 發 AJAX 請求嗎 no http://baidu.com:80 可以向 http://baidu.com:81 發 AJAX 請求嗎 no 瀏覽器必須保證 只有 協議+端口+域名 一模一樣才允許發 AJAX 請求
爲什麼要有同源策略?
爲什麼form表單提交沒有跨域問題,但ajax提交有跨域問題? - 方應杭的回答 - 知乎
因爲原頁面用 form 提交到另一個域名之後,原頁面的腳本無法獲取新頁面中的內容。所以瀏覽器認爲這是安全的。而 AJAX 是可以讀取響應內容的,因此瀏覽器不能允許你這樣做。如果你細心的話你會發現,其實請求已經發送出去了,你只是拿不到響應而已。所以瀏覽器這個策略的本質是,一個域名的 JS ,在未經允許的情況下,不得讀取另一個域名的內容。但瀏覽器並不阻止你向另一個域名發送請求。
簡單地說就是使用form發送請求,就會刷新頁面,所以原頁面沒有了,就認爲是安全的.但是Ajax可以吧響應內容讀取了.並且顯示在本頁面上.出現安全性問題
如果沒有同源策略,那麼任何網站都可以讀取別人的支付寶餘額等等
CORS 跨域
除了用jsonp之外,可以用CORS
下面我們用兩個網站來模擬Ajax跨域並且解決跨域問題
先寫前端的Ajax請求代碼
let myButton = document.getElementById('myButton'); myButton.addEventListener("click",(e)=>{ let request = new XMLHttpRequest(); request.onreadystatechange = ()=>{ if(request.readyState ===4){ console.log("請求和響應都完畢了"); if ( request.status>=200&&request.status<=400){ console.log('說明請求成功'); let string = request.responseText; //把符合json語法的字符串轉化爲js對應的值 let object2 = window.JSON.parse(string); console.log(object2) }else if(request.status>=400){ console.log("響應失敗"); } } } request.open('GET','http://jack.com:8002/xxx')//配置request.請求的路徑爲第二個網站的8002端口 request.send();//發送請求 })
服務器端的代碼
else if (path === '/xxx') { response.statusCode = 200 response.setHeader('Content-Type', 'text/xml;charset=utf-8') response.write(` { "note":{ "from":"mataotao", "to":"ni", } } `) response.end() }
監聽兩個端口,然後用mataotao.com:8001的網站向jack.com:8002網站發起請求,這就算是跨域發送請求
點擊點我後:
ajax請求因爲跨域問題沒有發送成功!
解決方法
一句代碼:設置請求頭:
//HTTP訪問控制(CORS)允許來自http://mataotao.com:8001的請求,並給予相應 response.setHeader('Access-Control-Allow-Origin','http://mataotao.com:8001')
else if (path === '/xxx') { response.statusCode = 200 response.setHeader('Content-Type', 'text/xml;charset=utf-8') //HTTP訪問控制(CORS)允許來自http://mataotao.com:8001的請求,並給予相應 response.setHeader('Access-Control-Allow-Origin','http://mataotao.com:8001') response.write(` { "note":{ "from":"mataotao", "to":"ni", } } `) response.end() }
然後重啓jack.com:8002的服務器,再重新請求一次
成功 CORS 可以告訴瀏覽器,我倆一家的,別阻止他
CORS的意思
突破同源策略 === 跨域
Cross-Origin Resource Sharing 跨域(源,站)資源共享
總結
CORS相對於JSONP,CORS可以發任意請求,而JSONP只能發送get請求
response.setHeader('Access-Control-Allow-Origin','http://mataotao.com:8001')
這句話是跨域(突破同源策略)的核心,即允許別的網站(例如http://mataotao.com:8001)跨域向我發請求,並且允許響應
Ajax總結
什麼是Ajax?
- 使用XMLHttpRequest發送請求
- 服務器返回json格式的字符串
- js解析json,並更新局部頁面
面試手寫Ajax
就是這9行代碼 一定要會!!!