咱們有不少種方式解決跨域請求
本篇爲你們講解使用CORS解決跨域html
CORS又稱跨域資源共享
它須要瀏覽器和服務器的同時支持
在開發過程當中,瀏覽器並不會有過多的變化
服務器是關鍵,只有服務器實現了CORS接口,才能夠進行跨域請求前端
CORS對於瀏覽器發過來的AJAX跨域請求分爲兩種:
簡單請求和非簡單請求java
所謂簡單請求就是HEAD,GET,POST三種請求方式
瀏覽器會在在header信息裏面多加一個字段:
key:origin
value:協議+域名+端口(如https://localhost:8080)ajax
服務器根據對象裏的origin值來決定是否贊成此次請求spring
若是請求經過
請求經過後,服務器會在header裏多增長几個字段:json
Access-Control-Allow-Origin: https://localhost:8080 Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: Token
解釋:
1.Credentials是否容許包含cookie,若是返回了true,那麼瀏覽器發送請求體的時候要添加:後端
var xhr = new XMLHttpRequest(); xhr.withCredentials = true;
如此這般,才能向服務器發送cookie跨域
2.Access-Control-Expose-Headers是多返回的字段名,根據實際需求改變瀏覽器
若是請求失敗
說明以前發送Origin的value不在許可範圍內
服務器會返回一個正常的HTTP迴應
瀏覽器發現,這個迴應的頭信息沒有包含Access-Control-Allow-Origin字段
從而拋出一個沒法跨域的異常(多是200,因此沒法識別)緩存
簡單請求的方法是Head,Get,Post
那麼非簡單請求的方法就是Put,Delete,或者Content-Type是application/json
非簡單請求在發出CORS請求以前,會增長一次HTTP查詢請求,也叫預檢請求
預檢請求成功了,瀏覽器才能發出XMLHttpRequest,不然報錯
若是瀏覽器發現這是一個非簡單請求
就會先發送一個預檢請求:
OPTIONS /cors HTTP/1.1 Origin: http://localhost:8088 Access-Control-Request-Method: PUT Access-Control-Request-Headers: token
預測請求的方法名叫OPTIONS
Origin和簡單請求同樣
Access-Control-Request-Method是請求方法
Access-Control-Request-Headers是額外發送的頭信息字段
(tip:預檢請求通常緩存下來,以便不須要在每次請求都發送)
若是預檢請求經過
咱們來看下服務器發出的迴應
HTTP/1.1 200 OK Date: Nov, 01 Dec 2017 01:15:39 GMT Server: Apache/2.0.61 (Unix) Access-Control-Allow-Origin: http://localhost:8088 Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: token Content-Type: text/html; charset=utf-8 Content-Encoding: gzip Content-Length: 0 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: text/plain
若是預檢請求失敗
服務器會返回一個HTTP迴應(沒有CORS的頭信息字段)
並在console打出not allowed by Access-Control-Allow-Origin
異常
預檢請求經過之後
瀏覽器發每次出的CORS請求就和簡單請求同樣
會有一個origin字段
服務器每次迴應都會有Access-Control-Allow-Origin
頭信息字段
前端jQuery寫法:
$.ajax({ type: "POST", url: baseUrl + "/post", dataType: 'json', crossDomain: true, xhrFields: { withCredentials: true }, data: { name: "name_from_frontend" }, success: function (response) { console.log(response)// 返回的 json 數據 $("#response").val(JSON.stringify(response)); } });
crossDomain: true是指開啓跨域
後端mvc配置類:
@Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**/*").allowedOrigins("*"); } }
這是spring4.2以上版本
若是是4.2如下的:
public class CrossDomainFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { response.addHeader("Access-Control-Allow-Origin", "*");// 若是提示 * 不行,請往下看 response.addHeader("Access-Control-Allow-Credentials", "true"); response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); response.addHeader("Access-Control-Allow-Headers", "Content-Type"); filterChain.doFilter(request, response); } }
4.2如下還需加過濾器:
<filter> <filter-name>CrossDomainFilter</filter-name> <filter-class>com.javadoop.filters.CrossDomainFilter</filter-class> </filter> <filter-mapping> <filter-name>CrossDomainFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
以上即是CORS請求的原理;
以爲還能夠的請點個贊,贊不了也能夠收藏下;
總之,謝謝閱讀~