您的位置:首页 > 新闻 > 资讯 > 装修公司展厅工艺样板_寻找电销团队合作_精准营销案例_无锡seo培训

装修公司展厅工艺样板_寻找电销团队合作_精准营销案例_无锡seo培训

2025/2/24 23:00:04 来源:https://blog.csdn.net/Mrqiang9001/article/details/144308122  浏览:    关键词:装修公司展厅工艺样板_寻找电销团队合作_精准营销案例_无锡seo培训
装修公司展厅工艺样板_寻找电销团队合作_精准营销案例_无锡seo培训

文章目录

    • 1摘要
    • 2 核心代码
      • 2.1 SpringBoot 全局跨域拦截器
      • 2.2 Nginx 配置跨域处理
      • 2.3 Nginx 和 SpringBoot 同时添加允许跨域处理会怎么样?
    • 3 推荐参考资料

1摘要

跨域问题报错信息:

Referrer Policy:strict-origin-when-cross-origin

跨域问题是在前后端分离的情况下一个非常常见的问题,通常添加一个跨域拦截器就可以解决,但是在后台添加后还是出现跨域问题,到底是配置错误还是哪里出了问题?

本文将基于 SpringBoot 2.7 从多种角度解决跨域问题。

2 核心代码

2.1 SpringBoot 全局跨域拦截器

核心跨域拦截代码

    /*** 跨域处理** @param registry*/@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowCredentials(true).allowedMethods("GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS","TRACE").allowedOriginPatterns("*").allowedHeaders("*").maxAge(3600);}

以上为高版本 SpringBoot 的跨域拦截器代码,SpringBoot 版本高于 2.4,SpringBoot 2.7 就用上边的代码。

关于 allowedOriginPatterns 方法说明:

点击 allowedOriginPatterns 方法,打开 Spring 的源码可以看到一下信息:

org.springframework.web.servlet.config.annotation.CorsRegistration#allowedOriginPatterns
	/*** Alternative to {@link #allowedOrigins(String...)} that supports more* flexible patterns for specifying the origins for which cross-origin* requests are allowed from a browser. Please, refer to* {@link CorsConfiguration#setAllowedOriginPatterns(List)} for format* details and other considerations.* <p>By default this is not set.* @since 5.3*/public CorsRegistration allowedOriginPatterns(String... patterns) {this.config.setAllowedOriginPatterns(Arrays.asList(patterns));return this;}

源码中一个关键信息点since 5.3, allowedOriginPatterns 是 Spring 框架 5.3 开始加入的

在 Maven 仓库中依赖信息可以看到 Springboot 2.7.18 使用的 Spring 版本是 5.3.31

仔细排查可发现 SpringBoot 2.4 开始是使用 Spring 5.3 的,因此高于 SpringBoot 2.4 的版本需要使用 allowedOriginPatterns 方法来设置允许跨域来源。低版本允许跨域来源的方法为 allowedOrigins

Maven 仓库查看SpringBoot 中依赖 Spring 的版本信息的地址为:

https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test/2.7.18

image-20241207110625671

如果不使用 allowedOriginPatterns 方法,还是使用旧的方法 allowedOrigins 则会报以下异常:

	 msg:When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a set of origins, list them explicitly or consider using "allowedOriginPatterns" instead.,trace:org.springframework.web.cors.CorsConfiguration.validateAllowCredentials(CorsConfiguration.java:473)org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:532)org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1266)org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1048)org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)

从报错信息中也可以看到Spring已经说明需要使用新的方法了。

完整的跨域处理拦截器代码:

package com.ljq.stock.alert.web.interceptor;import com.ljq.stock.alert.common.constant.TokenConst;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;/*** @Description: web 应用配置* @Author: Mr.lu*/
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {@BeanWebInterceptor webInterceptor() {return new WebInterceptor();}/*** 添加拦截器** @param registry*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(webInterceptor()).addPathPatterns("/**").excludePathPatterns(TokenConst.NO_TOKEN_API);}/*** 资源过滤** @param registry*/@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/swagger-ui/**").addResourceLocations("classpath:META-INF/resources/webjars/springfox-swagger-ui/");registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:META-INF/resources/webjars/");registry.addResourceHandler("/**").addResourceLocations("classpath:META-INF/resources/","classpath:resources/", "classpath:static/","classpath:public/");}/*** 跨域处理** @param registry*/@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowCredentials(true).allowedMethods("GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS","TRACE").allowedOriginPatterns("*").allowedHeaders("*").maxAge(3600);}}

其中 WebInterceptor 主要用于做 Token 鉴权拦截器,这里不在拓展。

2.2 Nginx 配置跨域处理

Nginx 允许跨域的配置如下:

    # HTTPS serverserver {listen       443 ssl;server_name  xxx.com;access_log  /var/log/nginx/xxx.access.log  main;ssl_certificate      /etc/ssl/certs/xxx.com.crt;ssl_certificate_key  /etc/ssl/certs/xxx.com.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {proxy_pass http://127.0.0.1:6666;proxy_set_header  Host $host;proxy_set_header   X-real-ip $remote_addr;proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Methods 'GET, POST,PUT, DELETE, OPTIONS';add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection upgrade;proxy_read_timeout 600s;if ($request_method = 'OPTIONS') {return 204;}}}

其中核心跨域配置为:

add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST,PUT, DELETE, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

也就是说即时 SpringBoot 项目中不配置跨域拦截器,直接在 Nginx 中配置允许跨域就可以实现跨域访问了,使用效果是一样的

2.3 Nginx 和 SpringBoot 同时添加允许跨域处理会怎么样?

如果 Nginx 配置了允许跨域请求,同时 SpringBoot 也添加了跨域拦截器,那会怎么样?是不是变得更强了?

实际测试的效果是不能跨域了。

浏览器报错如下:

image-20241207115608320

看后台接口日志是请求已经有返回了,但是前端还是提示跨域异常了(CORS error

点击具体的请求可以看到以下信息:

image-20241207113709757

请求状态码是 200,表明服务器请求通了,下边提示

Referrer Policy:strict-origin-when-cross-origin

这表明当前的请求是跨域请求

下边是关键点,返回的头里边包含了两个 access-control-allow-origin header,其中一个是 * 也就是允许跨域,另一个是当前请求的域名(非SpringBoot后台项目服务的域名),这还有正正的负的道理?

解决办法也很简单,要么删掉 Nginx 的跨域配置,要么删掉 SpringBoot 项目中的跨域拦截器。

这里作者推荐删除 Nginx 的跨域配置,因为如果项目迁移,Nginx 配置不属于项目代码,到时候出现明明好好的代码却跑不通了,那就是写代码的人的问题了。

至此,一个浏览器跨域导致的生产事故大案已经完美告破!!!

3 推荐参考资料

springboot和springframework版本依赖关系

Spring Boot Starter Test Maven 仓库依赖

nginx解决跨域和spring解决跨域

SpringBoot解决跨域问题/Nginx中配置解决跨域问题

解决The ‘Access-Control-Allow-Origin‘ header contains multiple values ‘*, *‘, but only one is allowed

SpringBoot 2/3 实现跨域报错:When allowCredentials is true, xxxxxxx , using “allowedOriginPatterns“ instead

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com