概念:
CORS(跨域資源共享)是一種機制,它使用額外的 HTTP 頭來告訴瀏覽器 讓運行在一個 origin (domain) 上的Web應用被准許訪問來自不一樣源服務器上的指定的資源。
發起請求的域與請求指向的域所在的資源不同,就造成了跨域。
域資源經常包括 協議、域名(IP)、端口號,若均相同,就是同域,若一個不相同,則是跨域。
跨域請求的安全問題
標籤<a> <form> <img> <script> <ifram> <link> <video> <audio>,都含有src屬性,可以發起請求,也就可能造成跨域。
瀏覽器之因此要對跨域請求做出限制,是出於安全方面的考慮,由於跨域請求可能會形成CSRF(Cross Site Request Forgery)攻擊。
用戶在A網站登陸後,攻擊者誘導用戶訪問一個攻擊頁面B,此時得到了用戶的信息,好比cookie,session、token等,此時A網站已信任用戶,
以用戶身份在攻擊頁面B,僞造用戶操做的請求,攻擊A網站。
模擬跨域
下面Demo模擬跨域。
新建兩個Js,man.js與cross.js,分別爲端口號 8888與8887 服務。
啓動好後, 使用 http://127.0.0.1:8888訪問,即出現跨域錯誤。
整個思想是: 請求8888端口服務時,會獲取html文檔,此文檔會當即訪問 8887端口服務。
main.js 8888端口
const http = require('http'); const fs = require('fs'); http.createServer((request, response) => { const html = fs.readFileSync('allowOrigin.html', 'utf8'); if (request.url === '/') { response.writeHead(200, { 'Content-Type': 'text/html' }); response.end(html); } }).listen(8888);
cross.js 8887 端口javascript
const http= require('http'); const fs = require('fs'); http.createServer( (request,response)=>{ console.log('服務器已經接受到了數據') response.writeHead(200,{ 'Content-Type':'text/html', 'Access-Control-Allow-Origin':'http://127.0.0.1' }); response.end('123'); }).listen(8887);
allowOrigin.html
<!DOCTYPE html> <html lang="en"> <body> <div>Access-Control-Allow-Origin</div> <script type="text/javascript"> let xhr=new XMLHttpRequest(); xhr.open('Get','http://127.0.0.1:8887'); xhr.send(); </script> </body> </html>
運行結果: 此時,瀏覽器會出現以下請求錯誤。html
其實, 瀏覽器發起請求時,並不知道請求是否跨域,所以仍然會發給服務器。
服務器接受請求後,纔會對此做出判斷,數據也返回了,只是被瀏覽器給攔截了。
所以,"服務器已經接受到了數據"這句話仍是會被 console 出來。
爲了解決這個跨域問題,須要將croos.js容許跨域的範圍改爲 'Access-Control-Allow-Origin':'http://127.0.0.1:8888' 。
與跨域相關的響應首部還有:
Access-Control-Allow-Methods
Access-Control-Allow-Headers
Access-Control-Allow-Credentiials