对于最新的稳定版本,请使用 Spring Data REST 5.0.4spring-doc.cadn.net.cn

配置 CORS

出于安全考虑,浏览器禁止向当前源(origin)之外的资源发起 AJAX 请求。在处理由浏览器发出的客户端 HTTP 请求时,您需要允许特定的 HTTP 资源可被访问。spring-doc.cadn.net.cn

从 2.6 版本起,Spring Data REST 通过 Spring 的 CORS 支持来实现跨域资源共享(CORS)。spring-doc.cadn.net.cn

仓库接口 CORS 配置

您可以在仓库接口上添加 @CrossOrigin 注解,以对该整个仓库启用 CORS。默认情况下,@CrossOrigin 允许所有源(origins)和 HTTP 方法。以下示例展示了一个跨源仓库接口的定义:spring-doc.cadn.net.cn

@CrossOrigin
interface PersonRepository extends CrudRepository<Person, Long> {}

在前面的示例中,整个 PersonRepository 已启用 CORS 支持。@CrossOrigin 提供了用于配置 CORS 支持的属性,如下例所示:spring-doc.cadn.net.cn

@CrossOrigin(origins = "http://domain2.example",
  methods = { RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE },
  maxAge = 3600)
interface PersonRepository extends CrudRepository<Person, Long> {}

前面的示例通过指定一个源(origin),为整个 PersonRepository 启用了 CORS 支持,该支持仅限于 GETPOSTDELETE 方法,并设置了最大缓存时间为 3600 秒。spring-doc.cadn.net.cn

仓库 REST 控制器方法 CORS 配置

Spring Data REST 完全支持在自定义 REST 控制器上使用 Spring Web MVC 的控制器方法配置,这些控制器与仓库共享基础路径,如下例所示:spring-doc.cadn.net.cn

@RepositoryRestController
public class PersonController {

  @CrossOrigin(maxAge = 3600)
  @RequestMapping(path = "/people/xml/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE)
  public Person retrieve(@PathVariable Long id) {
    // …
  }
}
使用 @RepositoryRestController 注解的控制器会从其关联的仓库继承 @CrossOrigin 配置。

全局 CORS 配置

除了基于注解的细粒度配置之外,你可能还想定义一些全局的 CORS 配置。这与 Spring Web MVC 的 CORS 配置类似,但可以在 Spring Data REST 中声明,并与细粒度的 @CrossOrigin 配置结合使用。默认情况下,允许所有来源以及 GETHEADPOST 方法。spring-doc.cadn.net.cn

现有的 Spring Web MVC CORS 配置不会应用于 Spring Data REST。

以下示例设置了一个允许的源,添加了 PUT 和 DELETE HTTP 方法,添加并暴露了一些头部,并设置了一小时的最大缓存时间:spring-doc.cadn.net.cn

@Component
public class SpringDataRestCustomization implements RepositoryRestConfigurer {

  @Override
  public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {

    cors.addMapping("/person/**")
      .allowedOrigins("http://domain2.example")
      .allowedMethods("PUT", "DELETE")
      .allowedHeaders("header1", "header2", "header3")
      .exposedHeaders("header1", "header2")
      .allowCredentials(false).maxAge(3600);
  }
}