Spring CORS Немає заголовка 'Access-Control-Allow-Origin'


86

Я отримую таку проблему після перенесення web.xml в конфігурацію Java

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

На основі кількох джерел Spring, спробували наступну спробу:

@Configuration
@ComponentScan(basePackageClasses = AppConfig.class, useDefaultFilters = false, includeFilters = {
        @Filter(org.springframework.stereotype.Controller.class) })
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/*").allowedOrigins("*").allowedMethods("GET", "POST", "OPTIONS", "PUT")
                .allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
                        "Access-Control-Request-Headers")
                .exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
                .allowCredentials(true).maxAge(3600);
    }

}

Вибрані значення були взяті з працюючого фільтра web.xml:

<filter>    
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
</init-param>
<init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
</init-param>
<init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
</init-param> </filter> <filter-mapping>

<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Будь-які ідеї, чому підхід до конфігурації Java Spring працює не так, як це робив файл web.xml?

Відповіді:


112

Змініть метод CorsMapping з registry.addMapping("/*")на на registry.addMapping("/**")in addCorsMappings.

Ознайомтеся з цією весняною документацією CORS .

З документації -

Увімкнути CORS для всієї програми так само просто, як:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Ви можете легко змінити будь-які властивості, а також застосувати цю конфігурацію CORS до певного шаблону шляху:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
            .allowedOrigins("http://domain2.com")
            .allowedMethods("PUT", "DELETE")
            .allowedHeaders("header1", "header2", "header3")
            .exposedHeaders("header1", "header2")
            .allowCredentials(false).maxAge(3600);
    }
}

Контролер методу контролера CORS

@RestController
@RequestMapping("/account")
public class AccountController {
  @CrossOrigin
  @RequestMapping("/{id}")
  public Account retrieve(@PathVariable Long id) {
    // ...
  }
}

Щоб увімкнути CORS для всього контролера -

@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

Ви навіть можете використовувати конфігурації CORS як на рівні контролера, так і на рівні методу; Потім Spring буде поєднувати атрибути обох анотацій для створення об’єднаної конфігурації CORS.

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin("http://domain2.com")
    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

36
Увімкнення CORS для всієї програми для мене не працює.
Dimitri Kopriwa

4
Використання addCorsMappingмені не підійшло, спокуса сказати, що це через весняну безпеку ..., проте додавання corsConfigurationSourceбобу, як пропонується тут, вирішило мою проблему.
Джеффрі

1
Також не слід забувати дозволити всім клієнтам registry.addMapping ("/ **"). AllowedOrigins ("*"); spring.io/guides/gs/rest-service-cors
SpaceDev

1
ти справді рятівник. Я використовую Spring 4.2 і спробував безліч інших альтернатив, і всі вони просто не працюють, доки я не спробував замінити метод addCorsMappings. Може допомогти чи не допомогти, додається стандартний заголовок CORS, а також заголовки Access-Control-Allow-Headers
Вирнах,

2
Його анотація 2020 року та весняна завантаження все ще не працює.
theprogrammer

14

Корисна порада - якщо ви використовуєте Spring data rest, вам потрібен інший підхід.

@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {

 @Override
 public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    config.getCorsRegistry().addMapping("/**")
            .allowedOrigins("http://localhost:9000");
  }
}

3
Дякую за цей допис. Я трохи втратив надію, коли помітив у вашому дописі, що Spring Data REST використовує інший підхід. Зараз мені повністю працює!
Джонатан Крегут,

2
RepositoryRestConfigurerAdapterзастаріло. Просто реалізує RepositoryRestConfigurerбезпосередньо.
Густаво Родрігес

9

У нас була та сама проблема, і ми вирішили її за допомогою XML-конфігурації Spring, як показано нижче:

Додайте це у свій контекстний xml-файл

<mvc:cors>
    <mvc:mapping path="/**"
        allowed-origins="*"
        allowed-headers="Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Authorization, X-Requested-With, requestId, Correlation-Id"
        allowed-methods="GET, PUT, POST, DELETE"/>
</mvc:cors>

4

Якщо ви використовуєте Spring Security ver> = 4.2, ви можете використовувати власну підтримку Spring Security замість того, щоб включати Apache:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Наведений вище приклад був скопійований із допису блогу Spring, в якому ви також можете знайти інформацію про те, як налаштувати CORS на контролері, конкретні методи контролерів тощо. Крім того, є також приклади конфігурації XML, а також інтеграція Spring Boot.


4

Відповідаючи на відповідь Омара, я створив новий файл класу у своєму проекті REST API, який називається WebConfig.javaз такою конфігурацією:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Це дозволяє будь-якому джерелу отримати доступ до API і застосовує його до всіх контролерів у проекті Spring.


4

Відповідь Омкара досить вичерпна.

Але якась частина глобальної конфігурації змінилася.

Згідно з посиланням на пружинний завантажувач 2.0.2.RELEASE

Станом на версію 4.2, Spring MVC підтримує CORS. Використання методу контролера CORS конфігурації з анотаціями @CrossOrigin у вашому додатку Spring Boot не вимагає жодної конкретної конфігурації. Глобальну конфігурацію CORS можна визначити, зареєструвавши компонент WebMvcConfigurer за допомогою налаштованого методу addCorsMappings (CorsRegistry), як показано в наступному прикладі:

@Configuration
public class MyConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**");
            }
        };
    }
}

WebMvcConfigurerAdapterОднак більшість відповідей у ​​цій публікації використовують

Тип WebMvcConfigurerAdapter застарілий

З весни 5 вам просто потрібно реалізувати інтерфейс WebMvcConfigurer:

public class MvcConfig implements WebMvcConfigurer {

Це тому, що Java 8 представила методи за замовчуванням на інтерфейсах, які охоплюють функціональність класу WebMvcConfigurerAdapter


1

відкритий клас TrackingSystemApplication {

    public static void main(String[] args) {
        SpringApplication.run(TrackingSystemApplication.class, args);
    }

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

}

0

У мене також були такі повідомлення No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

Я правильно налаштував корси, але чого не вистачало в webflux в RouterFuncion - це прийняти та заголовки контенту APPLICATION_JSON, як у цій частині коду:

@Bean
RouterFunction<ServerResponse> routes() {
    return route(POST("/create")
                              .and(accept(APPLICATION_JSON))
                              .and(contentType(APPLICATION_JSON)), serverRequest -> create(serverRequest);
}


0

З якихось причин, якщо все ще хтось не може обійти CORS, напишіть заголовок, який браузер хоче отримати доступ до вашого запиту.

Додайте цей компонент у свій файл конфігурації.

@Bean
public WebSecurityConfigurerAdapter webSecurity() {
    return new WebSecurityConfigurerAdapter() {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.headers().addHeaderWriter(
                    new StaticHeadersWriter("Access-Control-Allow-Origin", "*"));


        }
    };
}

Таким чином ми можемо сказати браузеру, що дозволяємо перехресне походження з усіх джерел. якщо ви хочете обмежити певний шлях, змініть "*" на {' http: // localhost: 3000 ', ""}.

Корисна довідка, щоб зрозуміти цю поведінку https://www.concretepage.com/spring-4/spring-4-rest-cors-integration-using-crossorigin-annotation-xml-filter-example


0

Я знайшов рішення у весняному завантаженні за допомогою анотації @CrossOrigin .

@RestController
@CrossOrigin
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.