首頁/ 汽車/ 正文

為什麼出現OPTIONS?SpringBoot介面跨域解決方案

引言

前後端分離的專案雖然降低了耦合度,但是引發的各種問題也隨之而來。後端專案由Tomcat部署(監聽8080埠),前端專案則部署在Nginx上(監聽80、443等非8080埠),前端頁面載入速度大大提高了,而當ajax請求後端介面的時候卻報錯了。

為什麼出現OPTIONS?SpringBoot介面跨域解決方案

同源策略

同源策略,它是由Netscape提出的一個著名的安全策略。現在所有支援JavaScript 的瀏覽器都會使用這個策略。所謂同源是指,域名,協議,埠相同。

前端地址: http://127。0。0。1:63344

後端地址: http://127。0。0。1:8080

這兩個地址雖然ip地址和協議都一樣,但是埠不一樣,所以並不滿足同源,這樣就造成了跨域的問題。

解決方案

配置addCorsMappings

新增一個類實現 WebMvcConfigurer 介面,然後給這個類加上 @Configuration 註解,最後實現 addCorsMappings 方法就ok了。

@Configurationpublic class WebMvcConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry。addMapping(“/**”) 。allowedOrigins(“*”) 。allowedMethods(“POST”, “GET”, “PUT”, “OPTIONS”, “DELETE”) 。maxAge(3600) 。allowCredentials(true); }}

@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry。addMapping(“/**”) 。allowedOrigins(“*”) 。allowedMethods(“POST”, “GET”, “PUT”, “OPTIONS”, “DELETE”) 。maxAge(3600) 。allowCredentials(true); } }

@Componentpublic class CorsInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { response。setHeader(“Access-Control-Allow-Origin”, “*”); response。setHeader(“Access-Control-Allow-Credentials”, “true”); response。setHeader(“Access-Control-Allow-Methods”, “GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS”); response。setHeader(“Access-Control-Max-Age”, “86400”); response。setHeader(“Access-Control-Allow-Headers”, “*”); // 如果是OPTIONS則結束請求 if (HttpMethod。OPTIONS。toString()。equals(request。getMethod())) { response。setStatus(HttpStatus。NO_CONTENT。value()); return false; } return true; }}

需將跨域攔截器放在校驗攔截器之上

我把原來的跨域配置

addCorsMappings

刪除了

@Configurationpublic class WebMvcConfig implements WebMvcConfigurer { @Resource private LoginInterceptor loginInterceptor; @Resource private CorsInterceptor corsInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // 跨域攔截器需放在最上面 registry。addInterceptor(corsInterceptor)。addPathPatterns(“/**”); // 校驗token的攔截器 registry。addInterceptor(loginInterceptor)。addPathPatterns(“/admin/**”); }}

OPTIOINS請求沒問題了

為什麼出現OPTIONS?SpringBoot介面跨域解決方案

也相繼傳送了GET請求

為什麼出現OPTIONS?SpringBoot介面跨域解決方案

總結

晚安!

為什麼出現OPTIONS?SpringBoot介面跨域解決方案

補充說明

Access-Control-Allow-Credentials 響應頭表示是否可以將對請求的響應暴露給頁面。返回 true 則可以,其他值均不可以。Credentials可以是 cookies, authorization headers 或 TLS client certificates。如果被設定為true,伺服器不得設定 Access-Control-Allow-Origin 的值為 *,需要指定域名,否則當需要傳送 Cookie 到伺服器時,瀏覽器響應時將會報錯。

測試

Ajax請求開啟 withCredentials 屬性

xhrFields: { withCredentials: true}

後端跨域配置不變時,瀏覽器請求結果報錯

為什麼出現OPTIONS?SpringBoot介面跨域解決方案

指定

Access-Control-Allow-Origin

的值為

http://127。0。0。1:63344

,再次請求後正常

為什麼出現OPTIONS?SpringBoot介面跨域解決方案

最終配置

@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { // 此處配置的是允許任意域名跨域請求,可根據需求指定 response。setHeader(“Access-Control-Allow-Origin”, request。getHeader(“origin”)); response。setHeader(“Access-Control-Allow-Credentials”, “true”); response。setHeader(“Access-Control-Allow-Methods”, “GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS”); response。setHeader(“Access-Control-Max-Age”, “86400”); response。setHeader(“Access-Control-Allow-Headers”, “*”); // 如果是OPTIONS則結束請求 if (HttpMethod。OPTIONS。toString()。equals(request。getMethod())) { response。setStatus(HttpStatus。NO_CONTENT。value()); return false; } return true; }

相關文章

頂部