Spring CORS Không có tiêu đề 'Access-Control-Allow-Origin'


85

Tôi gặp sự cố sau khi chuyển web.xml sang cấu hình java

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

Dựa trên một số tài liệu tham khảo Spring, nỗ lực sau đã được thử:

@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);
    }

}

Các giá trị đã chọn được lấy từ bộ lọc web.xml đang hoạt động:

<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>

Bất kỳ ý tưởng nào tại sao cách tiếp cận cấu hình java Spring không hoạt động như tệp web.xml đã làm?

Câu trả lời:


112

Thay đổi phương thức CorsMapping from registry.addMapping("/*")to registry.addMapping("/**")in addCorsMappings.

Kiểm tra Tài liệu CORS mùa xuân này .

Từ tài liệu -

Việc kích hoạt CORS cho toàn bộ ứng dụng đơn giản như sau:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Bạn có thể dễ dàng thay đổi bất kỳ thuộc tính nào, cũng như chỉ áp dụng cấu hình CORS này cho một mẫu đường dẫn cụ thể:

@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);
    }
}

Phương pháp điều khiển Cấu hình CORS

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

Để bật CORS cho toàn bộ bộ điều khiển -

@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) {
        // ...
    }
}

Bạn thậm chí có thể sử dụng cả cấu hình CORS cấp bộ điều khiển và cấp phương pháp; Sau đó, Spring sẽ kết hợp các thuộc tính từ cả hai chú thích để tạo cấu hình CORS được hợp nhất.

@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
Tôi không thể bật CORS cho toàn bộ ứng dụng.
Dimitri Kopriwa

4
Việc sử dụng addCorsMappingkhông hiệu quả với tôi, tôi muốn nói rằng đó là vì bảo mật mùa xuân ..., tuy nhiên việc thêm một corsConfigurationSourcehạt đậu như được đề xuất ở đây đã giải quyết được vấn đề của tôi.
Geoffrey

1
Cũng không nên quên cho phép tất cả các máy khách registry.addMapping ("/ **"). AllowOrigins ("*"); spring.io/guides/gs/rest-service-cors
spacedev

1
bạn thực sự là một cứu cánh. Tôi đang sử dụng Spring 4.2 và đã thử vô số lựa chọn thay thế khác và tất cả chúng chỉ đơn giản là không hoạt động cho đến khi tôi thử cách ghi đè addCorsMappings. Có thể có hoặc có thể không được thêm vào tiêu đề CORS tiêu chuẩn cũng như Access-Control-Allow-Headers
Vyrnach

2
Năm 2020 và chú thích khởi động mùa xuân của nó vẫn không hoạt động.
theprogrammer

14

Mẹo hữu ích - nếu bạn đang sử dụng phần còn lại dữ liệu Spring, bạn cần một cách tiếp cận khác.

@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {

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

3
Cảm ơn cho bài viết này. Tôi hơi mất hy vọng khi nhận thấy bài đăng của bạn nói rằng Spring Data REST sử dụng một cách tiếp cận khác. Hoàn toàn làm việc cho tôi bây giờ!
Jonathan Crégut

2
RepositoryRestConfigurerAdapterkhông được dùng nữa. Chỉ cần thực hiện RepositoryRestConfigurertrực tiếp.
Gustavo Rodrigues

9

Chúng tôi đã gặp vấn đề tương tự và chúng tôi đã giải quyết nó bằng cách sử dụng cấu hình XML của Spring như bên dưới:

Thêm cái này vào tệp xml ngữ cảnh của bạn

<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

Nếu bạn đang sử dụng Spring Security ver> = 4.2, bạn có thể sử dụng hỗ trợ gốc của Spring Security thay vì bao gồm Apache:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Ví dụ trên được sao chép từ một bài đăng trên blog Spring, trong đó bạn cũng có thể tìm thấy thông tin về cách cấu hình CORS trên bộ điều khiển, các phương pháp bộ điều khiển cụ thể, v.v. Ngoài ra, còn có các ví dụ cấu hình XML cũng như tích hợp Spring Boot.


4

Theo câu trả lời của Omar, tôi đã tạo một tệp lớp mới trong dự án API REST của mình được gọi WebConfig.javavới cấu hình này:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Điều này cho phép bất kỳ nguồn gốc nào truy cập vào API và áp dụng nó cho tất cả các bộ điều khiển trong dự án Spring.


4

Câu trả lời của Omkar khá toàn diện.

Nhưng một số phần của phần cấu hình toàn cầu đã thay đổi.

Theo tài liệu tham khảo Spring boot 2.0.2. RELEASE

Kể từ phiên bản 4.2, Spring MVC hỗ trợ CORS. Sử dụng phương pháp điều khiển CORS cấu hình với chú thích @CrossOrigin trong ứng dụng Spring Boot của bạn không yêu cầu bất kỳ cấu hình cụ thể nào. Cấu hình CORS toàn cầu có thể được xác định bằng cách đăng ký bean WebMvcConfigurer với phương thức addCorsMappings (CorsRegistry) tùy chỉnh, như được hiển thị trong ví dụ sau:

@Configuration
public class MyConfiguration {

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

WebMvcConfigurerAdapterTuy nhiên, hầu hết câu trả lời trong bài đăng này sử dụng

Loại WebMvcConfigurerAdapter không được dùng nữa

Kể từ Spring 5, bạn chỉ cần triển khai giao diện WebMvcConfigurer:

public class MvcConfig implements WebMvcConfigurer {

Điều này là do Java 8 đã giới thiệu các phương thức mặc định trên các giao diện bao gồm chức năng của lớp WebMvcConfigurerAdapter


1

public class 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

Tôi cũng có những tin nhắn như No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

Tôi đã định cấu hình các cors đúng cách, nhưng những gì còn thiếu trong webflux trong RouterFuncion là các tiêu đề accept và loại nội dung APPLICATION_JSON như trong đoạn mã này:

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


0

Vì lý do nào đó, nếu ai đó vẫn không thể vượt qua CORS, hãy viết tiêu đề mà trình duyệt muốn truy cập yêu cầu của bạn.

Thêm hạt đậu này vào bên trong tệp cấu hình của bạn.

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

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


        }
    };
}

Bằng cách này, chúng tôi có thể cho trình duyệt biết chúng tôi đang cho phép xuất xứ chéo từ mọi nguồn gốc. nếu bạn muốn hạn chế từ đường dẫn cụ thể, hãy thay đổi "*" thành {' http: // localhost: 3000 ', ""}.

Tham khảo hữu ích để hiểu hành vi này https://www.concretepage.com/spring-4/spring-4-rest-cors-integration-using-crossorigin-annotation-xml-filter-example


0

Tôi đã tìm thấy giải pháp trong khởi động mùa xuân bằng cách sử dụng chú thích @CrossOrigin .

@RestController
@CrossOrigin
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.