[TOC]
## 1. 跨域產生原因
瀏覽器同源策略限制(**DOM同源策略**、**XmlHttpRequest同源策略**)
## 2. http 跨域解決方案
### 2.1 JSONP
js 腳本可以不受跨域限制,所以通過使用 script 標簽來進行跨域請求,例如:
~~~
// 8080 端口向 9090 請求數據
const script = "<script type='text/javascript' src='http://localhost:9090/userList?callBack=getData'><\/script>";
$("head").append(script);
~~~
使用 jquery 指定返回類型為 jsonp 即可。更多關于 jsonp 實現的知識可查看 [jsonp 為什么不支持 post](https://www.jianshu.com/p/08e7732e3333)
>[warning] 但 JSONP 處理跨域有限制:只支持 get 請求方式。通過 script 標簽只指定了請求的 url,無法向服務端傳輸數據
### 2.2 CORS
>[success] CORS跨資源共享,由W3C推薦的方案,能使服務器支持 XmlHttpRequest 的跨域請求;使用CORS,只需要添加一些 HTTP 頭,讓服務器申明允許訪問的來源
* 使用 CORS 時,異步請求會被分為簡單請求與非簡單請求。[點擊查看更多關于簡單、非簡單請求知識](https://blog.csdn.net/yexudengzhidao/article/details/100104134)
* 同時滿足以下條件的我們稱之為簡單請求,除此之外均為非簡單請求
1. 請求方式為 get、post、head
2. HTTP的頭信息不超出以下幾種字段:
* Accept
* Accept-Language
* Content-Language
* Last-Event-ID
* Content-Type:只限于三個值 application/x-www-form-urlencoded、multipart/form-data、text/plain
>[warning] 在發起非簡單請求時,瀏覽器會先發起預檢請求(OPTIONS):瀏覽器詢問服務端當前網頁所在域是否被允許跨域,以及被允許使用的請求方式和頭信息字段,預檢通過,表示允許跨域。
## 3. 請求跨域案例:
### 3.1 由 withCredentials 屬性引起的跨域
當在前端請求中設置了 `withCredentials` 屬性為 `true` 時,后臺 `response header` 屬性 `Access-Control-Allow-Origin` 必須指定當前跨域的 **`域`** (當前為 * 即允許所有域請求),否則會報以上的請求錯誤
~~~
Access to XMLHttpRequest at 'http://域名:8081/userList' from origin 'http://域名:8080' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
~~~
解決方案:
~~~
// 指定當前跨域的域
Access-Control-Allow-Origin", "http://域名:8080"
~~~
## 4. XMLHTTPRequest 屬性
詳情參考 [XMLHTTPRequest屬性、方法、事件大全&詳解](https://segmentfault.com/a/1190000019891237)
常見的有:status、responseType
此外還有
* readyState:只讀,用于追蹤`xhr`當前的狀態值,從 0 到 4 分別標識服務端初始化狀態;open方法已調用;sent方法已調用;客戶端響應頭接收完成,響應體開始接收;HTTP響應已完全接收
* responseText:當 `responseType`為`text`、`""` 時,才可使用
* statusText:表示`HTTP`響應狀態的描述文本,如`OK`、`Not Found`等
* upload: 一個 `XMLHttpRequestUpload` 對象,用于收集傳輸信息。支持除 `onreadystatechange` 外 xhr 的事件回調
* timeout: 超時時間設置,默認 0ms ,即不設置
* withCredentials :Boolean 類型,指示是否攜帶類似 cookies, authorization 或者TLS客戶端證書跨域訪問控制,默認值為false 即不攜帶。在同一域下設置該屬性值無效