## 同源策略
**同源策略**是一個重要的安全策略,它用于限制一個origin的文檔或者它加載的腳本如何能與另一個源的資源進行交互。它能幫助阻隔惡意文檔,減少可能被攻擊的媒介。
如果兩個 URL 的?protocol、port都相同的話,則這兩個 URL 是同源。這個方案也被稱為“協議/主機/端口元組”,或者直接是?“元組”。(“元組” 是指一組項目構成的整體,雙重/三重/四重/五重/等的通用形式)
下表給出了與 URL?`http://a.b.com/dir/page.html`?的源進行對比的示例:
| URL | 結果 | 原因 |
| --- | --- | --- |
| http://a.b.com/dir2/other.html | 同源 | 只有路徑不同 |
| http://a.b.com/dir/inner/another.html| 同源 | 只有路徑不同 |
| https://a.b.com/secure.html | 失敗 | 協議不同 |
| http://a.b.com:81/dir/etc.html | 失敗 | 端口不同 (http://?默認端口是80) |
| http://c.b.com/dir/other.html | 失敗 | 主機不同 |
---
## 跨域請求
CORS即Cross Origin Resource Sharing(跨來源資源共享)。
所謂的跨域訪問或者跨域請求,就是是指通過 js 在不同的域之間進行數據傳輸或通信,比如用ajax向一個不同的域請求數據,或者通過js獲取頁面中不同域的框架中(iframe)的數據。只要協議、域名、端口有任何一個不同,都被當作是不同的域。
但不一定是瀏覽器限制了發起跨站請求,也可能是跨站請求可以正常發起,但是返回結果被瀏覽器攔截了。
## 解決方案
### jsonp
**JSONP原理:動態創建script標簽,使用script的src進行跨域**
**具體步驟:**
1. 判斷請求的與當前頁面域是否同源,如果同源正常發送ajax,如果不同源,生成一個script標簽
2. 生成一個隨機的callback名字,并生成對應名字的方法。
3. 設置script的src為要請求的接口,將callback參數拼接在后面。
4. 后端接收到請求后,開始準備要返回的數據
5. 后端拼接數據,將要返回的數據用callback包裹起來,將內容返回。
6. 瀏覽區接收到內容那個,會當做js代碼來執行。
7. 從而執行第二步生成的方法,這樣就接收到后端返回給我們的對象。
由于jsonp的原理就是使用script標簽進行跨域,而script都是使用get方式請求數據。所以jsonp跨域只能是get方法,即使你設置的post方法,jQuery也會自動轉為get方法。
### CROS
1. 跨域資源共享是一份瀏覽器技術的規范,以避開瀏覽器的同源策略,是 JSONP 模式的現代版。
2. CORS背后的思想,就是使用自定義的HTTP頭部讓瀏覽器與服務器進行溝通,從而決定請求或響應是應該成功,還是應該失敗。
3. 與 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。用 CORS 可以讓前端工程師用一般的 XMLHttpRequest,這種方式的錯誤處理比 JSONP 要來的好;另一方面,JSONP 可以在不支持 CORS 的老舊瀏覽器上運作。現代的瀏覽器都支持 CORS。
具體做法:客戶端不需要做什么,只需要在服務器端發送一個響應頭即可:‘Access-Control-Allow-Origin’;
1. 如若允許所有域訪問:Access-Control-Allow-Origin: \*;如:header("Access-Control-Allow-Origin: \*");
2. 如若只允許指定域訪問:Access-Control-Allow-Origin: 域名A;如:header("Access-Control-Allow-Origin: http://www.test2.com");
CORS分為兩種
1、**簡單請求**
2、**復雜請求**
1. 請求方法是以下三種方法之一:
HEAD,GET,POST
2. HTTP請求頭信息不超出以下幾種字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三個值application/x-www-form-urlencoded、multipart/form-data、text/plain
**凡是不同時滿足上面兩個條件,就屬于非簡單請求。**
瀏覽器對這兩種請求的處理,是不一樣的。
Access-Control-Allow-Origin: http://www.test.com
Access-Control-Max-Age: 3628800
Access-Control-Allow-methods: GET, PUT, DELETE, POST
Access-Control-Allow-Header: content-type
Access-Control-Allow-Credentail: true
“Access-Control-Allow-Origin"表明它允許”?http://www.test.com?"發起跨域請求
"Access-Control-Max-Age"表明在3628800秒內,不需要再發送預檢驗請求,可以緩存該結果(上面的資料上我們知道CROS協議中,一個AJAX請求被分成了第一步的OPTION預檢測請求和正式請求)
"Access-Control-Allow-Methods"表明它允許GET、PUT、DELETE的外域請求
"Access-Control-Allow-Headers"表明它允許跨域請求包含content-type頭
"Access-Control-Allow-Credentials"表明它允許cookies
---
**復雜請求**表面上看起來和簡單請求使用上差不多,但實際上瀏覽器發送了不止一個請求。其中最先發送的是一種"預請求",此時作為服務端,也需要返回"預回應"作為響應。預請求實際上是對服務端的一種權限請求,只有當預請求成功返回,實際請求才開始執行。
預請求以OPTIONS形式發送,當中同樣包含域,并且還包含了兩項CORS特有的內容:
> Access-Control-Request-Method?– 該項內容是實際請求的種類,可以是GET、POST之類的簡單請求,也可以是PUT、DELETE等等。
> Access-Control-Request-Headers?– 該項是一個以逗號分隔的列表,當中是復雜請求所使用的頭部。
顯而易見,這個預請求實際上就是在為之后的實際請求發送一個權限請求,在預請求回應返回的內容當中,服務端應當對這兩項進行回復,以讓瀏覽器確定請求是否能夠成功完成。
> Access-Control-Allow-Origin(必含) – 和簡單請求一樣的,必須包含一個域。
> Access-Control-Allow-Methods(必含) – 這是對預請求當中Access-Control-Request-Method的回復,這一回復將是一個以逗號分隔的列表。盡管客戶端或許只請求某一方法,但服務端仍然可以返回所有允許的方法,以便客戶端將其緩存。
> Access-Control-Allow-Headers(當預請求中包含Access-Control-Request-Headers時必須包含) – 這是對預請求當中Access-Control-Request-Headers的回復,和上面一樣是以逗號分隔的列表,可以返回所有支持的頭部。這里在實際使用中有遇到,所有支持的頭部一時可能不能完全寫出來,而又不想在這一層做過多的判斷,沒關系,事實上通過request的header可以直接取到Access-Control-Request-Headers,直接把對應的value設置到Access-Control-Allow-Headers即可。
一旦預回應如期而至,所請求的權限也都已滿足,則實際請求開始發送。
- 序言
- 從業感悟
- 常用名詞
- HTML
- JS
- ES6新特性
- jquery和vue對比
- 徹底理解this
- JQuery添加自定義函數
- js的實現
- 原始值和引用值
- MYSQL
- 簡介
- 術語
- 特點
- 范式
- 數據類型1
- 數據類型2
- 編碼
- 權限管理
- 事務
- mvvc
- 引擎
- MyISAM與InnoDB區別
- 索引類型
- 鎖
- 死鎖
- 分層架構
- 執行計劃
- join原理
- 高可用
- 日志類型
- 分庫分表
- 中間件
- 服務器
- 操作系統
- 信號量 鎖 隊列
- PHP
- composer加載原理
- composer基礎知識
- 自動加載函數
- composer加載代碼
- composer 自動加載
- 內存管理
- PHP執行流程
- cgi,fastCgi,php-fpm
- HTTP
- 錯誤碼
- 跨域請求
- 面試
- 安全
- HTTP劫持
- 設計模式
- 如何正確的使用設計模式
- 單例模式
- 原型模式
- 簡單工廠模式
- 工廠方法模式
- 抽象工廠模式
- 建造者模式
- 設計原則
- 算法
- PHP短標簽