Spring Boot 解決跨域問(wèn)題的 3 種方案
來(lái)源:r6d.cn/XTrB
問(wèn)題背景:
Same Origin Policy,譯為“同源策略”。它是對(duì)于客戶(hù)端腳本(尤其是JavaScript)的重要安全度量標(biāo)準(zhǔn),其目的在于防止某個(gè)文檔或者腳本從多個(gè)不同“origin”(源)裝載。
它認(rèn)為自任何站點(diǎn)裝載的信賴(lài)內(nèi)容是不安全的。當(dāng)被瀏覽器半信半疑的腳本運(yùn)行在沙箱時(shí),它們應(yīng)該只被允許訪(fǎng)問(wèn)來(lái)自同一站點(diǎn)的資源,而不是那些來(lái)自其它站點(diǎn)可能懷有惡意的資源。
CORS簡(jiǎn)介:
詳解響應(yīng)頭:
Access-Control-Allow-Origin 該字段必填。它的值要么是請(qǐng)求時(shí)Origin字段的具體值,要么是一個(gè)*,表示接受任意域名的請(qǐng)求。 Access-Control-Allow-Methods 該字段必填。它的值是逗號(hào)分隔的一個(gè)具體的字符串或者*,表明服務(wù)器支持的所有跨域請(qǐng)求的方法。注意,返回的是所有支持的方法,而不單是瀏覽器請(qǐng)求的那個(gè)方法。這是為了避免多次"預(yù)檢"請(qǐng)求。 Access-Control-Expose-Headers 該字段可選。CORS請(qǐng)求時(shí),XMLHttpRequest對(duì)象的getResponseHeader()方法只能拿到6個(gè)基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必須在Access-Control-Expose-Headers里面指定。 Access-Control-Allow-Credentials 該字段可選。它的值是一個(gè)布爾值,表示是否允許發(fā)送Cookie.默認(rèn)情況下,不發(fā)送Cookie,即:false。對(duì)服務(wù)器有特殊要求的請(qǐng)求,比如請(qǐng)求方法是PUT或DELETE,或者Content-Type字段的類(lèi)型是application/json,這個(gè)值只能設(shè)為true。如果服務(wù)器不要瀏覽器發(fā)送Cookie,刪除該字段即可。 Access-Control-Max-Age 該字段可選,用來(lái)指定本次預(yù)檢請(qǐng)求的有效期,單位為秒。在有效期間,不用發(fā)出另一條預(yù)檢請(qǐng)求。
解決辦法:
第一種辦法:
import?org.springframework.context.annotation.Configuration;
import?org.springframework.web.servlet.config.annotation.CorsRegistry;
import?org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public?class?CorsConfig?implements?WebMvcConfigurer?{
????@Override
????public?void?addCorsMappings(CorsRegistry?registry)?{
????????registry.addMapping("/**")
????????????????.allowedOrigins("*")
????????????????.allowedMethods("GET",?"HEAD",?"POST",?"PUT",?"DELETE",?"OPTIONS")
????????????????.allowCredentials(true)
????????????????.maxAge(3600)
????????????????.allowedHeaders("*");
????}
}
/**
?*?An?implementation?of?{@link?WebMvcConfigurer}?with?empty?methods?allowing
?*?subclasses?to?override?only?the?methods?they're?interested?in.
?*
?*?@author?Rossen?Stoyanchev
?*?@since?3.1
?*?@deprecated?as?of?5.0?{@link?WebMvcConfigurer}?has?default?methods?(made
?*?possible?by?a?Java?8?baseline)?and?can?be?implemented?directly?without?the
?*?need?for?this?adapter
?*/
@Deprecated
public?abstract?class?WebMvcConfigurerAdapter?implements?WebMvcConfigurer?{}
第二種辦法:
import?org.springframework.context.annotation.Configuration;
import?javax.servlet.*;
import?javax.servlet.annotation.WebFilter;
import?javax.servlet.http.HttpServletResponse;
import?java.io.IOException;
@WebFilter(filterName?=?"CorsFilter?")
@Configuration
public?class?CorsFilter?implements?Filter?{
????@Override
????public?void?doFilter(ServletRequest?req,?ServletResponse?res,?FilterChain?chain)?throws?IOException,?ServletException?{
????????HttpServletResponse?response?=?(HttpServletResponse)?res;
????????response.setHeader("Access-Control-Allow-Origin","*");
????????response.setHeader("Access-Control-Allow-Credentials",?"true");
????????response.setHeader("Access-Control-Allow-Methods",?"POST,?GET,?PATCH,?DELETE,?PUT");
????????response.setHeader("Access-Control-Max-Age",?"3600");
????????response.setHeader("Access-Control-Allow-Headers",?"Origin,?X-Requested-With,?Content-Type,?Accept");
????????chain.doFilter(req,?res);
????}
}
第三種辦法:
public?class?GoodsController?{
????@CrossOrigin(origins?=?"http://localhost:4000")
????@GetMapping("goods-url")
????public?Response?queryGoodsWithGoodsUrl(@RequestParam?String?goodsUrl)?throws?Exception?{}
}??
@Target({?ElementType.METHOD,?ElementType.TYPE?})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public?@interface?CrossOrigin?{}
評(píng)論
圖片
表情
