網(wǎng)站首頁 編程語言 正文
1.解決問題:When allowCredentials is true, xxxxxxx , using “allowedOriginPatterns“ instead
2.3版本跨域配置如下
/**
* 跨域問題解決
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.allowedHeaders("*")
.maxAge(3600)
.allowCredentials(true);
}
}
1.1.解決方法:
????????Spring官網(wǎng)有類似問題:https://github.com/spring-projects/spring-framework/issues/26111
????????大致意思為:提供了allowedOriginPatterns方法供使用。原本的allowCredentials為true時(shí),allowedOrigins不能使用 * 號(hào)匹配
/**
* 跨域問題解決
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowedMethods("*")
.allowedHeaders("*")
.maxAge(3600)
.allowCredentials(true);
}
}
其實(shí)解決跨域大分類有2種方式,一種是利用注解,一種寫個(gè)配置類?
2.解決跨域的幾種方式
2.1.CorsFilter 方式設(shè)置跨域
????????CorsFilter過濾器:通過Spring Boot的CORS過濾器來處理跨域請(qǐng)求,需要定義一個(gè)CorsFilter Bean,例如:
@Configuration
public class CoreFilter {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOriginPattern("*"); // 不是 addAllowedOrigin
config.setAllowCredentials(true);
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return new CorsFilter(source);
}
}
2.2.攔截器實(shí)現(xiàn)跨域
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.io.Serializable;
@Configuration
@RequiredArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer, Serializable {
private static final long serialVersionUID = 1L;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
// 不是 addAllowedOrigin
.allowedOriginPatterns("*")
.allowedMethods("*")
.allowedHeaders("*")
.maxAge(3600)
.allowCredentials(true);
}
/**
* 修改訪問路徑
* @param configurer
*/
public void configurePathMatch(PathMatchConfigurer configurer) {
// 設(shè)置為true后,訪問路徑后加/ 也能正常訪問 /user == /user/
configurer.setUseTrailingSlashMatch(true);
}
}
????????與使用 CorsFilter 方式一樣,當(dāng) allowCredentials 為 true時(shí),不可以將 allowedOrigins 設(shè)置為 *,必須用 allowedOriginPatterns。否則最終也會(huì)到 CorsConfiguration#validateAllowCredentials 方法中的校驗(yàn)。
2.3.通過 @CrossOrigin 實(shí)現(xiàn)跨域
@CrossOrigin 可以標(biāo)注類和單個(gè)方法。使用@CrossOrigin注解標(biāo)注在Controller類或方法上,指定允許跨域的源地址、請(qǐng)求方法、Header等屬性
標(biāo)注類:
該 Controller 請(qǐng)求路徑下的所有方法都允許跨域。
@CrossOrigin(origins = "http://example.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@RequestMapping(method = RequestMethod.GET, path = "/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
????????在類級(jí)別上添加了?@CrossOrigin
。因此,retrieve()
?和?remove()
?方法都啟用了?@CrossOrigin
。我們可以通過指定以下注解屬性的值來自定義配置:origins
、methods
、allowedHeaders
、exposedHeaders
、allowCredentials
?或?maxAge
。
標(biāo)注方法:
僅標(biāo)注的方法允許跨域。
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@RequestMapping(method = RequestMethod.GET, path = "/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
在上面的示例中,我們只為?retrieve()
?方法啟用了 CORS。我們可以看到,我們沒有為?@CrossOrigin
?注解設(shè)置任何配置,因此它使用的是默認(rèn)值:
- 允許所有 origin。
- 允許使用的 HTTP 方法是?
@RequestMapping
?注解(本例中為?GET
)中指定的方法。 - 緩存預(yù)檢響應(yīng)的時(shí)間(maxAge)為 30 分鐘。
在類上和方法上
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin("http://example.com")
@RequestMapping(method = RequestMethod.GET, "/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
Spring 將合并兩個(gè)注解的屬性,創(chuàng)建合并的 CORS 配置。
這里,兩個(gè)方法的?maxAge
?都是?3600
?秒,remove()
?方法允許所有 origin,而?retrieve()
?方法只允許來自?http://example.com
?的 origin。
2.4.nginx
Nginx反向代理:將請(qǐng)求轉(zhuǎn)發(fā)給Nginx,由Nginx統(tǒng)一處理跨域請(qǐng)求,例如:
location /api/ {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://localhost:8080;
}
2.5.webFilter
使用@WebFilter注解:該注解可以直接在過濾器類上使用,并指定過濾的url,類似于xml文件中配置的filter
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@Component
@WebFilter(urlPatterns = "/*")
@Order(-99999)
public class CorsFilter extends HttpFilter {
private static final long serialVersionUID = 2386571986045107652L;
private static final String OPTIONS_METHOD = "OPTIONS";
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
String origin = req.getHeader(HttpHeaders.ORIGIN);
if (!StringUtils.isEmpty(origin)) {
// 允許客戶端的域
res.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
// 允許客戶端提交的Header
String requestHeaders = req.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS);
if (!StringUtils.isEmpty(requestHeaders)) {
res.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders);
}
// 允許客戶端訪問的Header
res.addHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");
// 允許客戶端攜帶憑證信息
res.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
// 允許客戶端請(qǐng)求方法
res.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, OPTIONS, DELETE");
if (OPTIONS_METHOD.equalsIgnoreCase(req.getMethod())) {
res.setStatus(HttpServletResponse.SC_NO_CONTENT);
res.setContentType(MediaType.TEXT_HTML_VALUE);
res.setCharacterEncoding("utf-8");
res.setContentLength(0);
res.addHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "1800");
return;
}
}
super.doFilter(req, res, chain);
}
}
原文鏈接:https://blog.csdn.net/qq_20957669/article/details/132616061
- 上一篇:沒有了
- 下一篇:沒有了
相關(guān)推薦
- 2022-10-07 Android開發(fā)Jetpack組件Lifecycle原理篇_Android
- 2023-02-17 Python排序算法之堆排序算法_python
- 2022-10-31 Kotlin協(xié)程開發(fā)之Flow的融合與Channel容量及溢出策略介紹_Android
- 2023-06-17 C語言中帶返回值的宏定義方式_C 語言
- 2023-04-12 C#?DataGridView行列轉(zhuǎn)換的具體實(shí)現(xiàn)_python
- 2022-09-01 ASP.NET輕量級(jí)MVC框架Nancy的基本用法_實(shí)用技巧
- 2022-10-12 常見Android編譯優(yōu)化問題梳理總結(jié)_Android
- 2022-11-05 Android?Jetpack組件中LifeCycle作用詳細(xì)介紹_Android
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支