XHR對象用於與服務器交互。經過XMLHttpRequest
能夠在不刷新頁面的狀況下請求特定URL,獲取數據。XMLHttpRequest
在AJAX
編程中被大量使用。前端
MDN文檔nginx
Fetch API提供了一個獲取資源的接口(包括跨域請求)ajax
MDN文檔編程
Asynchronous JavaScript And XML,是一種使用XMLHttpRequest
技術構建更復雜,動態的網頁的編程實踐。大部分的ajax其實就是對XMLHttpRequest
的相關API進行封裝,使其使用起來更加方便。json
MDN文檔segmentfault
跨域,顧名思義,跨越區域。大概意思爲訪問的網站請求非同源資源。後端
因爲安全性等問題,瀏覽器自帶同源策略,所謂同源是指域名,協議,端口均相同。當訪問的網站須要請求非同源資源時,瀏覽器將拒絕這些非同源請求。在這種狀況下,咱們須要解決瀏覽器跨域時拒絕請求非同源資源的限制。跨域
當瀏覽器出現跨域時,那就不可避免的引出兩個關鍵的概念了。簡單請求和非簡單請求。 瀏覽器
當跨域產生時,非簡單請求會在真正向服務端發送請求前進行預檢請求(OPTIONS),。緩存
一、條件定義:若請求知足如下全部的條件,則請求可視爲簡單請求。
一、條件定義:若請求知足下列任一條件時,即應首先發送預檢請求(options)。
JSON with Padding,是JSON的一種使用模式,可讓網頁從別的網域獲取資料。因爲同源策略,通常來講位於server1.example.com的網頁沒法與不是server1.example.com的服務器溝通,而HTML的<script>元素是一個例外。利用<script>元素的這個開放策略,網頁就能夠實現跨域獲取後端接口數據。
因爲使用script標籤的src屬性,所以只支持get方法。
當使用JSONP這種方案時,先後端都要有相對應的寫法。
大體流程就是,前端經過<script>標籤的src屬性向後臺接口發起請求(只支持GET請求),而且傳遞參數callback='response'
,與此同時,前端必須定義函數response(responseData)
,這是用來處理接口返回數據後一些操做。
當接口收到請求,返回數據格式爲response(responseData)
。這樣,當前端接受到數據response(responseData)
,就恰好執行了咱們已經定義好的response(...)
當報錯以下時:
緣由是:後端接口沒有返回callback(...)
Cross Origin Resource Sharing,跨域資源共享,由一系列傳輸的HTTP頭組成,這些HTTP頭決定瀏覽器是否阻止前端JavaScript代碼獲取跨域請求的響應。
一、Access-Control-Allow-Origin:指示請求的資源能共享給哪些域
二、Access-Control-Allow-Credentials:指示當請求的憑證標記爲true
時,是否響應該請求
三、Access-Control-Allow-Headers:用在對預請求的響應中,哪些HTTP方法容許訪問請求的資源
四、Access-Control-Expose-Headers:指示哪些HTTP頭的名稱能在響應中列出
五、Access-Control-Max-Age:指示預請求的結果能被緩存多久
六、Access-Control-Request-Headers:用於發起一個預請求,告知服務器正式請求會使用哪些HTTP頭
七、Access-Control-Request-Method:用於發起一個預請求,告知服務器正式請求會使用哪種HTTP請求方法
八、Origin:指示獲取資源的請求是從什麼域發起的
koa2中接口容許跨域響應,響應頭部字段設置以下:
ctx.set('Access-Control-Allow-Origin', '*'); ctx.set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE, PUT'); ctx.set('Access-Control-Allow-Headers', 'X-Requested-With, User-Agent, Referer, Content-Type, Cache-Control,accesstoken'); ctx.set('Access-Control-Max-Age', '86400'); ctx.set('Access-Control-Allow-Credentials', 'true');
注意事項:
若添加了自定義的Header字段,必須將這個字段名添加到服務端響應頭部Access-Control-Allow-Headers中,否則會報錯。
項目踩坑:
在接口響應中添加了以上容許跨域響應的頭部字段,可是在開發中還報了跨域的錯誤(Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request
),報錯的大體意思是預檢請求禁止重定向。通過排查,發現是服務端nginx作了HTTP到HTTPS的重定向設置,而我剛好是以http+ip地址的形式發起請求的,那麼請求就被重定向到https了,然而,瀏覽器發起的預檢請求是禁止重定向的,所以報錯了。解決方案就是將請求地址改成https+域名的形式,這樣預檢請求就不會重定向了。