如何在春季启动中启用 CORS - 不起作用

2022-09-02 13:43:14

我正在尝试在我的Spring Boot应用程序中启用CORS,但它根本无法正常工作。


我试过

我不知道目前如何解决此问题,也不知道CORS无法正常工作的问题。


我的代码

控制器

@RestController
public class DbController {

    @Autowired
    private IDAO conn;

    @CrossOrigin
    @GetMapping("/foo")
    public List<Foo> getFoo() {
        return conn.getFooFromDao();
    }
}

    @Repository
    public class DaoImpl implements IDAO {

    @Autowired
    private JdbcTemplate temp;

    public List<Foo> getFooFromDao() {

        List<Foo> data = new ArrayList<>();

        String sql = "SELECT fooName FROM BigFoo ORDER BY fooName ASC;";

        data.addAll(temp.query(sql, new BeanPropertyRowMapper(BigFoo.class)));
        return data;
    }
}

预期

我希望我的控制器可以通过任何方法从任何源/域访问。

实际值

我的控制器无法任何源/域访问。它给我的Angular前端一个错误:

编辑:我在前端的错误

从源“http://localhost:4200”访问“localhost:8080/foo”的XMLHttpRequest已被CORS策略阻止:跨域请求仅支持协议方案:http,data,chrome,chrome-extension,https。

第二次编辑

这是我在Angular(前端)中的代码:

服务

getFoo() {
    return this.http.get("localhost:8080/foo");
  }

我正在使用从HttpClientimport { HttpClient } from "@angular/common/http";

我还通过将URL复制并粘贴到我的浏览器中来验证该URL在该服务方法中是否有效。它确实返回JSON,这省略了错误URL或拼写错误的可能性。


答案 1

将交叉源放在控制器级别本身

@RestController
@CrossOrigin(origins = "*")
public class DbController {

    @Autowired
    private IDAO conn;

    @GetMapping("/foo")
    public List<Foo> getFoo() {
        return conn.getFooFromDao();
    }
}

这是spring推荐的直接解决方案,您还可以定义一个过滤器,该过滤器将允许所有响应的交叉源

@Component
public class SimpleCORSFilter implements Filter {

private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);

public SimpleCORSFilter() {
    log.info("SimpleCORSFilter init");
}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");

    chain.doFilter(req, res);
}

  @Override
  public void init(FilterConfig filterConfig) {}

  @Override
  public void destroy() {}

}

另外,您需要知道,您在代码快照中没有提到协议http或https,并且您还没有发送GET请求,当您开始订阅它时,请求将被发送,如下所示

getFoo() {
    return this.http.get("http://localhost:8080/foo");
}

getFoo().subscribe(resp -> { // your logic });

// or directly inside getFoo() like this 
getFoo() {
    return this.http.get("http://localhost:8080/foo")
    .subscribe(resp -> { // your logic });
}

答案 2

您需要为注释添加原点@CrossOrigin(origins = "*")