带有 Spring Boot 2 的 CORS [重复]

Posted

技术标签:

【中文标题】带有 Spring Boot 2 的 CORS [重复]【英文标题】:CORS with Spring Boot 2 [duplicate] 【发布时间】:2019-07-21 16:03:42 【问题描述】:

我正在尝试将我的 Angular 应用程序连接到我的新 Spring Boot 2 控制器。我开始一切,我得到:

Access to XMLHttpRequest at 'localhost:8093/restapi/setup' from origin 'http://localhost:4200' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

接着是:

ERROR HttpErrorResponse headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: "localhost:8093/restapi/setup", ok: false, …

所以这是 CORS,对吗?当我从邮递员那里点击localhost:8093/restapi/setup 时,我得到了一个有效的回复,正如你所期望的那样。

所以我做了一些研究,特别是我发现了这个:No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API

我终于在这里找到了这篇文章:

https://chariotsolutions.com/blog/post/angular-2-spring-boot-jwt-cors_part1/

这导致我得到以下代码:

@Configuration
public class ManageConfiguration 
    private static final Logger         LOGGER = LogManager.getLogger(ManageConfiguration.class);

    @Bean
    public CorsFilter corsFilter() 
        LOGGER.debug("Configuring CORS");
        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);
    

所以我认为这很简单,现在再试一次,我得到:

Access to XMLHttpRequest at 'localhost:8093/restapi/setup' from origin 'http://localhost:4200' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

接着是:

ERROR HttpErrorResponse headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: "localhost:8093/restapi/setup", ok: false, …

所以它似乎没有任何区别。

检查并在正确的端口上运行:

2019-02-27 14:23:21.261  INFO 9814 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8093 (http) with context path ''

确保它包含我的 CORS bean:

2019-02-27 14:23:19.608 DEBUG 9814 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'corsFilter'
...
o.springframework.web.filter.CorsFilter  : Filter 'corsFilter' configured for use

根据How can you debug a CORS request with cURL?,我做了以下 curl 请求来查看我的飞行前资料。

$ curl -H "Origin: http://example.com" --verbose http://localhost:8093/restapi/setup
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8093 (#0)
> GET /restapi/setup HTTP/1.1
> Host: localhost:8093
> User-Agent: curl/7.61.0
> Accept: */*
> Origin: http://example.com
> 
< HTTP/1.1 200 
< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< Access-Control-Allow-Origin: http://example.com
< Access-Control-Allow-Credentials: true
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Wed, 27 Feb 2019 21:38:28 GMT
< 
* Connection #0 to host localhost left intact
"issueType":["bug","epic","subTask","task","story"]

一天来我一直在为下一步要尝试什么而摸不着头脑,但什么也想不出来。有什么建议吗?

【问题讨论】:

在您的前端 javascript 代码中,您似乎忘记在请求 URL 中包含“https://”或“http://”部分。在***.com/questions/46258449/…查看答案 @sideshowbarker ***** 的儿子!你在钱上是对的。我想知道为什么它在谈论 CORS 支持的协议。应该是一个线索。您应该发布作为答案,以便我可以给您信用。 【参考方案1】:

我认为您发送的 ajax 请求在请求 URL 中没有 http:// 协议前缀,请尝试从 ajax 中点击 http://localhost:8093/restapi/setup

【讨论】:

【参考方案2】:

在您的代码中添加此 WebSecurityConfigurerAdapter

import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter 

  @Override
  protected void configure(HttpSecurity http) throws Exception 
    http.cors().and().csrf().disable();
  


同时添加以下WebMvcConfigurer

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 WebMvcConfigurerImpl implements WebMvcConfigurer 

  @Override
  public void addCorsMappings(CorsRegistry registry) 
    registry.addMapping("/**");
  

最后在你的 rest 控制器类的顶部添加这个注解:@CrossOrigin。

@CrossOrigin
public class RestController 
// Your methods

如果你有过滤器,你可以在响应中添加以下属性,如果你没有,你可以使用这个。

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Service;
import org.springframework.web.filter.OncePerRequestFilter;

@Service
public class JwtAuthenticationFilter extends OncePerRequestFilter 

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException 

    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
    response.setHeader("Access-Control-Expose-Headers", "Content-Length, Authorization");
    filterChain.doFilter(request, response);
  


【讨论】:

我没有过滤器,所以我使用了您提供的过滤器。我将您建议的两个类和 @CrossOrigin 注释添加到我的休息控制器(这应该是多余的)。行为没有变化。【参考方案3】:
@Configuration
public class CorsConfig 

    @Bean
    public WebMvcConfigurer corsConfigurer() 
        return new WebMvcConfigurerAdapter() 
            @Override
            public void addCorsMappings(CorsRegistry registry) 
                registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
                        .allowedHeaders("*");
            
        ;
    


@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter 

    @Override
    public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/**");
    

请看这里的教程https://spring.io/blog/2015/06/08/cors-support-in-spring-framework

【讨论】:

以上是关于带有 Spring Boot 2 的 CORS [重复]的主要内容,如果未能解决你的问题,请参考以下文章

带有 Keycloak 的 Angular 和 Spring Boot REST API 的 CORS 问题

带有 Keycloak 的 Angular 和 Spring Boot REST API 的 CORS 问题

带有 Google 的 OAuth2 - CORS 错误(Angular + Spring boot)[重复]

WebTestClient - 带有 Spring Boot 和 Webflux 的 CORS

在带有 Angular 的 Spring Boot 中启用了 Cors,但仍然出现 cors 错误

带有 spring-boot 和 angularjs 的 CORS 不起作用