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) 中包含具有值 trueapp.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 错

Spring Boot-Angular - 在地址栏中输入 Url 导致 404

Spring Boot + Angular 应用程序