同源策略規定,AJAX 請求(XMLHttpRequest
)只能發給同源的網址,不然就會出錯。所謂的同源策略是指 3 個相同:協議相同、域名相同、端口相同。html
好比 http://www.example.com/index.html
這個網址,協議是http
,域名是 www.example.com
,端口是默認的 80
。若是你在這個網站上使用 AJAX 發送 http://www.example1.com/index.html
請求,就會出錯,由於域名不一樣。前端
AJAX 跨域的根本緣由是瀏覽器不容許這麼作(不是服務端的問題),瀏覽器限制 AJAX 跨域請求的目的是爲了保證用戶信息的安全,防止數據被惡意獲取。jquery
2.1 JSONP 如何解決跨域問題git
<img src="">
與 <script src="">
標籤<script>
一樣的方式發送請求,把返回的 JSON 數據封裝,而後以 JS 腳本形式返回callback
參數請求跨域服務端,服務端返回數據時用 callback
參數名做爲返回的函數名來包裹住返回的 JSON 數據2.2 JSONP 示例github
這裏咱們以 MOOC 網爲例,當訪問 https://www.imooc.com/
時,會發送一個 https://www.imooc.com/index/getstarlist
AJAX 請求,下面是訪問後返回的 JSON 數據。
spring
咱們以 JONP 的形式(https://www.imooc.com/index/getstarlist?callback=test
)訪問。
json
2.3 JSONP 的弊端後端
AbstractJsonpResponseBodyAdvice
切面,不過如今這個類已通過時了,也就是說如今不推薦使用 JSONP 來解決跨域問題GET
方式的請求XMLHttpRequest
請求(script
),因此不支持異步事件等,不過這也是爲何 JSONP 能夠解決跨域問題的緣由CORS 跨資源共享(Cross-origin resource sharing)是一種機制,它經過添加 HTTP 頭信息,解決 AJAX 跨域資源訪問問題。跨域
CORS 請求能夠分爲兩類:簡單請求與非簡單請求,主要區別是非簡單請求在進行訪問以前,會發送一個預檢請求。「預檢」請求首先經過 OPTIONS 方法向另外一域上的資源發送HTTP請求,以便肯定實際請求是否安全發送。爲了防止每次非簡單請求以前都發送預檢請求,能夠在服務端設置預檢請求的緩存的時間。瀏覽器
3.1 簡單請求
HEAD
、GET
、POST
中的 1 種header
中沒有自定義的請求頭Content-Type
爲如下幾種:application/x-www-form-urlencoded
、multipart/form-data
、text/plain
3.2 非簡單請求
header
中包含自定義請求頭 的 AJAX 請求PUT
、DELETE
形式的 AJAX 請求Content-Type
字段的類型是 application/json
等我本身在本地寫了一個測試跨域的 demo(Spring Boot),經過端口 8082 發出請求(攜帶自定義的請求頭)訪問端口爲 8081 的服務。下面是 Chrome 控制檯有關 HTTP 的控制信息。
經過上面的圖能夠看出 CORS 解決跨域問題的關鍵所在,添加必要的請求頭與響應頭信息,下面是有關的頭信息介紹。
3.3 HTTP 響應首部字段
Access-Control-Allow-Origin
:指定了容許訪問該資源的外域 URI。對於不須要攜帶身份憑證的請求,服務器能夠指定該字段的值爲通配符,表示容許來自全部域的請求。Access-Control-Allow-Methods
:指明瞭實際請求所容許使用的 HTTP 方法Access-Control-Expose-Headers
:在跨域訪問時,XMLHttpRequest
對象的getResponseHeader()
方法只能拿到一些最基本的響應頭,若是要攜帶自定義的請求頭,須要在該首部中進行容許的請求頭放入白名單Access-Control-Max-Age
:非簡單請求預檢命令的最大緩存時間,在緩存時間內,對於非簡單請求,不會再發送預檢請求Access-Control-Allow-Credentials
:是否容許攜帶身份憑證(Cookie)的請求3.4 HTTP 請求首部字段
Origin
:代表預檢請求或實際請求的源 URLAccess-Control-Request-Method
:用於預檢請求。其做用是,將實際請求所使用的 HTTP 方法告訴服務器Access-Control-Request-Headers
:用於預檢請求。其做用是,將實際請求所攜帶的首部字段告訴服務器能解決跨域的方式還有不少,好比禁止瀏覽器的跨域、Nginx 解決跨域等。這裏只講解了兩種常見的跨域方式,由於 JSONP 存在一些弊端,所以推薦使用 CORS 等方式來解決跨域問題。
跨域問題,涉及到不少有關 HTTP 協議 的知識,但願你們重視計算機基礎知識。上面那個測試的 demo 上傳到了 GitHub,demo 是用 Spring Boot 實現的,有須要的能夠點我前往~
跨域資源共享 CORS 詳解l
【原創】說說JSON和JSONP,也許你會豁然開朗,含jQuery用例
Cross-Origin Resource Sharing (CORS)