跨域請求詳解

跨域請求整體分爲兩種類型:簡單請求和複雜請求,即simple request和preflight request。ajax

1、簡單請求spring

simple request的請求須要,知足如下條件:跨域

1.請求方法只能是GET,HEAD,POST瀏覽器

2.Accept、Accept-Language、Content-Language、Content-Type、DPR、Downlink、Save-Data、Viewport-Width、Width服務器

3.第二個條件中的Content-Type只能是application/x-www-form-urlencoded、multipart/form-data、text/plain其中的一種app

4.沒有特殊js代碼(參考https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests)url

對於simple request請求,儘管這個請求是跨域的,它也會被瀏覽器直接放行。spa

可是瀏覽器拿到response後並不會把 response 直接暴露給用戶程序,而是去檢查這個 response 的 headers 中有沒有 Access-Control-Allow-Origin,以及這個 header 的 value 包含 request 發出的地址(也就是「域」)。code

若是兩個條件都知足, response 會被返回給發出請求的程序;若是沒有這個 header 或者 value 不對, response 就會被攔截下來,由於在瀏覽器看來,這個 response 不屬於你,由於服務器沒有明確容許你這個「域」來請求它。orm

2、複雜請求

 對於複雜請求,瀏覽器先發送一個pre-flight請求,一般是一個OPTIONS方法的請求,根據服務器響應的response的headers進行校驗,若校驗經過,則代表服務器容許訪問,再發送真正的請求。

 一般要校驗的數據項有:Access-Control-Allow-OriginAccess-Control-Allow-Methods、Access-Control-Allow-Headers以及其餘的Access-Control-*數據項。

下面是咱們的一個跨域請求示例。本機63342端口的網頁經過ajax訪問8080端口的接口,存在跨域問題。

第一個是pre-flight請求,服務器收到請求並響應,response header中返回了Access-Control-Allow-Origin、Access-Control-Allow-Methods以及Access-Control-Allow-Headers等,

表示當前服務器容許http://localhost:63342域的GET請求(而且該請求包含name爲authorization的header數據)訪問。若是不符合該條件則真正的請求不會被髮送。

由於咱們的請求符合服務器所要求的的條件,因此真正的請求被髮送,請求數據以下:

我麼能夠看到請求成功,一個完整的跨域請求就完成了。

spring4.2以後提供了@CrossOrigin註解來代表接口的跨域特性。

springMVC的請求流程是Request->Dispatchservlet->HandlerMappin(uri和handler的映射關係)->HandlerAdapter(適配器用於執行handler)->ModerAndView->ViewResolver->Response

CrossOrigin註解在HandlerAdapter階段起做用,當檢測到請求是preflight請求(知足三個條件,請求方法爲OPTIONS、請求head包含Origin和Access-Control-Request-Method)時,

spring給本次請求適配的handler是PreFlightHandler實例,該handler專門處理preflight請求,判斷是否拒絕訪問或者容許訪問時容許訪問的域、請求方法、請求必須的header。

真正的請求發送以後就是則會通過CorsInterceptor攔截器,其前置方法preHandle也會對跨域請求進行校驗,校驗經過則設置一些響應數據頭,而後交給下一級攔截器或者controller處理,校驗不經過則響應瀏覽器禁止訪問。

相關文章
相關標籤/搜索