最近在琢磨前后端分離,難免會碰到跨域問題裁替。
首先弄清楚项玛,跨域指的是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本。它是由瀏覽器的同源策略造成的弱判,是瀏覽器施加的安全限制襟沮。
何為同源?
URL由協(xié)議昌腰、域名开伏、端口和路徑組成,如果兩個URL的協(xié)議剥哑、域名和端口相同硅则,則表示他們同源。
同源策略(是瀏覽器實施的)
瀏覽器的同源策略株婴,限制了來自不同源的"document"或腳本對當前"document"讀取或設(shè)置某些屬性 —— 從一個域上加載的腳本不允許訪問另外一個域的文檔屬性怎虫。
在瀏覽器中暑认,<script>、<img>大审、<iframe>蘸际、<link>等標簽都可以加載跨域資源,而不受同源限制徒扶,但瀏覽器限制了JavaScript的權(quán)限使其不能讀粮彤、寫加載的內(nèi)容。
另外同源策略只對網(wǎng)頁的HTML文檔做了限制姜骡,對加載的其他靜態(tài)資源如javascript导坟、css、圖片等仍然認為屬于同源圈澈。
解決方案
對于跨域常見的解決方案一般會想到以下幾種方案
- 使用jsonp惫周。
- 修改document.domain跨子域
- iframe
- 反向代理
若想要詳細了解以上解決方案,自行百度康栈,本文主要介紹使用跨域資源共享CORS來解決跨域問題
首先CORS需要瀏覽器和服務器同時支持递递。
瀏覽器直接發(fā)出CORS請求。在頭信息之中啥么,增加一個Origin字段登舞。Origin字段用來說明,本次請求來自哪個源悬荣。服務器根據(jù)這個值菠秒,決定是否同意這次請求。
服務器返回一個正常的http回應氯迂。瀏覽器查看回應的頭信息沒有包含Access-Control-Allow-Origin字段稽煤,檢查自己是否所處其中。若不在其中囚戚,拋出一個錯誤,被XMLHttpRequest的onerror回調(diào)函數(shù)捕獲轧简。若在其中驰坊,則CORS請求成功。
注意:Access-Control-Allow-Origin字段是html5新增的一項標準功能哮独,因此 IE10以下版本的瀏覽器是不支持的拳芙,因此,如果要求兼容IE9或更低版本的ie瀏覽器皮璧,會導致使用此種方式的跨域請求以及傳遞Cookie的計劃夭折
預檢請求
瀏覽器將CORS請求分為兩類: 簡單請求和非簡單請求舟扎。
非簡單請求是那種對服務器有特殊要求的請求,比如請求方法是PUT或DELETE悴务,或者Content-Type字段的類型是application/json睹限。
例如譬猫,下面的前端代碼向后臺發(fā)送了一個非簡單請求,因為它制定了'Content-type': 'application/json'
非簡單請求的CORS請求羡疗,會在正式通信之前染服,增加一次HTTP查詢請求,稱為"預檢"請求叨恨。
預檢請求的請求方法是OPTIONS,請求的頭信息包括兩個特殊字段:
- Access-Control-Request-Method
該字段是必須的柳刮,用來列出瀏覽器的CORS請求會用到哪些HTTP方法。 - Access-Control-Request-Headers
該字段是一個逗號分隔的字符串痒钝,指定瀏覽器CORS請求會額外發(fā)送的頭信息字段秉颗。
服務器回應的其他CORS相關(guān)字段:
- Access-Control-Allow-Methods
該字段必需,它的值是逗號分隔的一個字符串送矩,表明服務器支持的所有跨域請求的方法蚕甥。注意,返回的是所有支持的方法益愈,而不單是瀏覽器請求的那個方法梢灭。這是為了避免多次"預檢"請求。 - Access-Control-Allow-Headers
如果瀏覽器請求包括Access-Control-Request-Headers字段蒸其,則Access-Control-Allow-Headers字段是必需的敏释。它也是一個逗號分隔的字符串,表明服務器支持的所有頭信息字段摸袁,不限于瀏覽器在"預檢"中請求的字段钥顽。 -
Access-Control-Max-Age
該字段可選,用來指定本次預檢請求的有效期靠汁,單位為秒蜂大。在此期間,不用發(fā)出另一條預檢請求蝶怔。
AccessControl.png