最近Vue項目中使用axios組件,在頁面交互中發現axios會發送兩次請求,一種請求方式爲OPTIONS,另一種爲本身設置的。html
CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。 它容許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。java
CORS須要瀏覽器和服務器同時支持。目前,全部瀏覽器都支持該功能,IE瀏覽器不能低於IE10。ios
實現CORS通訊的關鍵是服務器。只要服務器實現了CORS接口,就能夠跨域通訊。詳情見:先後分離調用API接口跨域問題web
瀏覽器將CORS請求分紅兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。spring
只要同時知足如下兩大條件,就屬於簡單請求。json
(1) 請求方法是如下三種方法之一:axios
- HEAD
- GET
- POST
(2)HTTP的頭信息不超出如下幾種字段:後端
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限於三個值
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
凡是不一樣時知足上面兩個條件,就屬於非簡單請求。跨域
非簡單請求是那種對服務器有特殊要求的請求,好比請求方法是PUT
或DELETE
,或者Content-Type
字段的類型是application/json
。瀏覽器
非簡單請求的CORS請求,會在正式通訊以前,增長一次HTTP查詢請求,稱爲"預檢"請求(preflight)。
瀏覽器先詢問服務器,當前網頁所在的域名是否在服務器的許可名單之中,以及可使用哪些HTTP動詞和頭信息字段。只有獲得確定答覆,瀏覽器纔會發出正式的XMLHttpRequest
請求,不然就報錯。
瀏覽器對這兩種請求的處理,是不同的。
先後端未知足「同源策略/SOP」,俗稱請求跨域。瀏覽器一旦發現請求跨域,就會使用CORS通訊,自動添加一些附加的頭信息,簡單請求只會有一次請求,只有非簡單請求會附加一次請求。
服務期端直接經過「預檢」請求,服務器新建攔截器,攔截全部請求,篩選全部Requset Method:OPTIONS的請求,不作任何處理直接返回便可。
package com.yhzy.zytx.jwt.Interceptor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method; /** * @ClassName JwtInterceptor * @Description JWT攔截器 * @Author 天生傲骨、怎能屈服 * @Date 2019/5/22 13:48 * @Version 1.0 */ public class JwtInterceptor implements HandlerInterceptor { private final static Logger logger = LoggerFactory.getLogger(JwtInterceptor.class); public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception { // 從 http 請求頭中取出 token String token = httpServletRequest.getHeader("Authorization"); // 若是不是映射到方法直接經過 if(!(object instanceof HandlerMethod)){ return true; } HandlerMethod handlerMethod=(HandlerMethod)object; Method method=handlerMethod.getMethod(); // OPTIONS請求類型直接返回不處理 if ("OPTIONS".equals(httpServletRequest.getMethod())){ return false; } return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } }
完結
但願能夠幫到你們,xxxx !