春季:CrossOrigin无法与ResponseEntity合作

时间:2019-09-24 14:38:40

标签: java spring cors

关于在春季启用CORS的问题很多,但似乎并非所有这些问题都有有效的答案,或者被接受的答案对我的情况不起作用。因此,我要提出这个问题,看看是否有人可以帮助我。

我一直在尝试对API的响应启用CORS响应,我试图在方法中甚至向类控制器添加@CrossOrigin注释,以使其起作用,但两种方法都无效。我也尝试过在应用程序引导程序配置或实现Bean的类配置上创建WebMvcConfigurer,但最终结果仍然相同。

起初,我认为可能是因为我用ResponseEntity实例返回响应,而不是像大多数示例所示那样仅返回实际值,但是即使替换了我返回值的方式,结果还是相同。没有CORS标头附加到响应中,即使在请求时在OPTIONS http方法中也不附加,它仅以没有Cross Origin Allow的普通标头进行响应。

因此,为了展示我如何努力实现CORS,这是我的RestController类之一:

package com.vod.cloudservice.controller;

import com.vod.cloudservice.entity.Series;
import com.vod.cloudservice.service.SeriesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

@RestController
@RequestMapping("/series")
public class SeriesController {
    @Autowired
    SeriesService seriesService;

    @CrossOrigin
    @GetMapping
    public ResponseEntity<List<Series>> getSeriesList() {
        List<Series> seriesList = this.seriesService.findAll();

        return new ResponseEntity<>(seriesList, HttpStatus.OK);
    }

    // More resources ahead.
}

单独执行此操作无效。所以我创建了一个这样的配置类:

package com.vod.cloudservice.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("*")
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
            .allowedHeaders("Content-Type")
            .maxAge(3600);
    }
}

即使这样,响应仍然相同。并且如果它有助于知道如何向希望启用CORS的控制器发送完整请求,则请求的执行方式如下:

GET: http://localhost:8080/series

我可能会通过截取响应并手动添加标头来解决此问题,但是我想更好地控制响应,例如,我想处理一个类中X个允许的方法。 >

2 个答案:

答案 0 :(得分:-1)

我对此事进行了更多研究,发现provider "aws" { version = "~> 2.0" } locals { project_id = "it_broke_like_3_collar_watch" } terraform { required_version = ">= 0.12" } resource aws_default_vpc default { } data aws_subnet_ids subnets { vpc_id = aws_default_vpc.default.id } resource aws_efs_file_system efs { creation_token = local.project_id encrypted = true } resource aws_efs_mount_target target { depends_on = [ aws_efs_file_system.efs ] count = length(data.aws_subnet_ids.subnets.ids) file_system_id = aws_efs_file_system.efs.id subnet_id = tolist(data.aws_subnet_ids.subnets.ids)[count.index] } 批注使得响应标头在处理RestController批注时已经被写入CORS处理程序无法写入已发送的内容。

因此,在我的情况下,我创建了一个过滤器类,它将在响应中添加CORS标头,如下所示:

CORS

此后,我只需要将过滤器注册为public class HttpFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { httpServletResponse.setHeader("Access-Control-Allow-Origin", "*"); httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); httpServletResponse.setHeader("Access-Control-Allow-Headers", "Content-Type"); httpServletResponse.setHeader("Access-Control-Max-Age", "3600"); filterChain.doFilter(httpServletRequest, httpServletResponse); } } ,然后它就可以工作了,尽管不是我最初想要的那样,但是它至少为我提供了工作所需的结果。

答案 1 :(得分:-2)

allowedHeaders("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Authorization, Origin, Accept, Access-Control-Request-Method, Access-Control-Request-Headers");