Angular 6 + Spring Boot:错误:“来自原点 'http://localhost:4200' 已被 CORS 策略阻止”
Posted
技术标签:
【中文标题】Angular 6 + Spring Boot:错误:“来自原点 \'http://localhost:4200\' 已被 CORS 策略阻止”【英文标题】:Angular 6 + Spring Boot: Error: "from origin 'http://localhost:4200' has been blocked by CORS policy"Angular 6 + Spring Boot:错误:“来自原点 'http://localhost:4200' 已被 CORS 策略阻止” 【发布时间】:2019-10-26 21:25:36 【问题描述】:我正在尝试将 Angular 6 项目与 Spring Boot 应用程序连接起来。当我运行 Angular 项目时,虽然我已经安装了所有依赖项和导入,但它不断给出这个错误。
我在控制器类中使用了以下代码行。
@CrossOrigin(origins = "http://localhost:4200/", maxAge = 3600)
我还在 java 文件夹中包含了这个 SimpleCORSFilter.java 文件:
package com.oms;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class SimpleCORSFilter implements Filter
private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);
public SimpleCORSFilter()
log.info("SimpleCORSFilter init");
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
HttpServletRequest request = (HttpServletRequest) req;
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, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
chain.doFilter(req, res);
@Override
public void init(FilterConfig filterConfig)
@Override
public void destroy()
我还在 Angular 项目中创建了 proxy.conf.json 文件:
"/api":
"target": "http://localhost:8080",
"secure": false
这个文件是这样包含在 angular.json 中的:
"start": "ng serve --proxy-config proxy.conf.json",
我仍然收到此错误:
访问 XMLHttpRequest 在 'http://localhost:8080/fetchAll' 来自原点 “http://localhost:4200”已被 CORS 策略阻止:请求 头字段授权不允许 预检响应中的 Access-Control-Allow-Headers。**
我提到了这种类型的查询,但无法得到确切的解决方案。
我真的很困惑,如果代码中有任何错误?应该采取什么措施来解决这个问题?
【问题讨论】:
将 SimpleCORSFilter.java 代码更改为response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, X-Requested-With, remember-me")
。即,将Authorization
添加到值中。错误消息,“在预检响应中 Access-Control-Allow-Headers 不允许请求标头字段授权” 正是由于代码不包含 Authorization
在它的值中Access-Control-Allow-Headers 响应标头的设置。
@sideshowbarker 是的,它奏效了。非常感谢!
【参考方案1】:
出现此错误是因为请求包含一些您的 CORS 过滤器配置中未提及的附加标头。
为了在开发过程中添加 CORS 支持,我一般更喜欢在 spring 配置文件下面添加。您还需要在您的应用程序配置文件 (application.properties) 中包含具有值 true
的 app.cors.enabled
键才能使其工作。
import org.springframework.context.annotation.Bean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@ConditionalOnProperty(name = "app.cors.enabled")
/**
* If the value of the key "app.cors.enabled" is true in application.properties file,
* then only this configuration will be enabled.
*
*/
public class SpringConfig
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurer()
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/*").allowedHeaders("*").allowedOrigins("*").allowedMethods("*")
.allowCredentials(true);
;
确保对于生产环境,从配置文件中删除 app.cors.enabled
键或将其值设置为 false
。如果您在生产环境中也需要 CORS 支持,请确保使用固定值,而不是使用 *
允许所有值
一旦你这样做了,你的控制器上就不需要 @CrossOrigin
注释了。
【讨论】:
能否解释一下代码中app.cors.enabled的使用?app.cors.enabled
只是为了使这个 CORS 支持可配置。通常,对于 Angular 应用程序开发,我们需要在 Java 后端启用 CORS 支持,但是一旦您将 Angular 的构建代码与后端应用程序合并,则不需要此支持,因此只需通过此配置键 app.cors.enabled
,您可以在生产中禁用 CORS 支持环境。【参考方案2】:
当您使用 Spring Boot 时,我建议您在配置中添加 CorsFilter bean,而不是引入 CORS 过滤器。让我知道这是否有帮助。
@Bean
public CorsFilter corsFilter()
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
config.addAllowedMethod("PUT");
config.addAllowedMethod("DELETE");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
快乐编码:)
【讨论】:
是的,我尝试在配置中添加这个文件,它成功了。感谢您的帮助。 很高兴它对你有用,重要的是希望你理解这个问题 我在我的配置类中添加了这个 "public class AuthServerConfig extends AuthorizationServerConfigurerAdapter implements Filter" 并添加了这个方法 "@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException" 。 ..仍然没有运气【参考方案3】:问题在于带有弹簧靴的过滤器的排序。在您的CORSFilter
上添加此注释:@Order(Ordered.HIGHEST_PRECEDENCE)
。
这将确保您的 CORSFilter
具有最高的执行优先级(最优先)。
【讨论】:
当我输入此注释时,“Ordered”仍未解决。 未解决是什么意思?你没有收到它的包裹吗?应该从org.springframework.core.Ordered
导入
是的,我没有收到包,但现在这个导入有帮助。谢谢。【参考方案4】:
请添加一个 servlet 过滤器并添加以下代码。 它应该工作。 添加 "Access-Control-Allow-Headers", "*" 是强制性的。 不需要创建 proxy.conf.json。
@Component
@Order(1) 公共类 MyProjectFilter 实现过滤器
@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-Expose-Headers", "Content-Disposition");
response.setHeader("Access-Control-Allow-Methods", "GET,POST,PATCH,DELETE,PUT,OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-Max-Age", "86400");
chain.doFilter(req, res);
【讨论】:
我尝试了上述方法,但仍然抛出 CORS 预检错误。在这种情况下我需要使用 Spring Security 吗?在本地没有 CORS 过滤器的情况下工作,在生产中不起作用。 您的 UI 代码必须通过通用网关(网络服务器)通过 HTTPS 协议与后端应用服务器交互。您需要为该公共网关设置数字证书。以上是关于Angular 6 + Spring Boot:错误:“来自原点 'http://localhost:4200' 已被 CORS 策略阻止”的主要内容,如果未能解决你的问题,请参考以下文章
如何保护 Angular 6 - Spring Boot 微服务应用程序 [关闭]
如何在 Angular 6 中显示 Spring Boot Data JPA Query 的响应
同一服务器上的两个项目具有不同的端口,但客户端(Angular 6)无法调用服务器(Spring Boot)
spring boot 2.6.0 使用swagger报 ‘documentationPluginsBootstrapper‘; java.lang.NullPointerException 错