弹簧靴中的 CORS 不起作用 - 得到空响应
Posted
技术标签:
【中文标题】弹簧靴中的 CORS 不起作用 - 得到空响应【英文标题】:CORS in spring boot is not working - getting empty response 【发布时间】:2020-04-20 15:57:44 【问题描述】:我将 Spring Boot (Tomcat + Java) 用于我的后端应用程序,并将 React 用于我的前端。 我正在尝试从“http://localhost:3000”访问“http://localhost:8080/vr-backend-0.0.1-SNAPSHOT/stockdata/NIFTY19DECFUT?from=2019-12-03&to=2019-12-03”。
我在控制器级别和端点级别都添加了@CrossOrigin(origins = "*")。我得到空的结果。 我在控制器级别和端点级别都添加了@CrossOrigin。结果是空的。
如果我删除 @CrossOrigin 注释,我会收到 Cors 错误。这意味着注释是必要的。错误是“访问从源'http://localhost:3000'获取'http://localhost:8080/vr-backend-0.0.1-SNAPSHOT/stockdata/NIFTY19DECFUT?from=2019-12-03&to=2019-12-03'已被CORS策略阻止:请求的资源上不存在'Access-Control-Allow-Origin'标头。如果提供不透明的响应根据您的需要,将请求的模式设置为 'no-cors' 以获取禁用 CORS 的资源。”
如果我直接将链接复制粘贴到浏览器中,它可以正常工作并返回 JSON。 如果我调用“https://cdn.rawgit.com/rrag/react-stockcharts/master/docs/data/MSFT.tsv”,它也会返回结果。
为避免拼写错误,我使用了 console.log,并从 console.log 中粘贴了这些内容。
我正在使用 fetch 进行“获取”。
[编辑 1] 我正在查看 tomcat 日志,很快就会更新。
[编辑 2] TL;博士 这不是 CORS 问题。
完整说明: 1.“http://localhost:8080/vr-backend-0.0.1-SNAPSHOT/stockdata/NIFTY19DECFUT?from=2019-12-03&to=2019-12-03”的响应是200。
我登录了 spring boot 应用并查看了 tomcat 日志。它达到了控制器方法,我从数据库中得到了正确的结果。当我发回响应时,我在浏览器中得到空结果。如前所述,如果我直接点击 url,我会得到正确的结果。
这不是预检 OPTIONS 请求。
所以可以断定不是CORS问题。 @CrossOrigin 注释有效
我在发布问题后查看了日志。所以这个问题可以关闭,因为它是不正确的。如果我无法解决空响应问题,我将发布一个单独的问题,因为这个问题的标题具有误导性。
谢谢大家的回复。
【问题讨论】:
请使用***.com/q/59555658/441757 编辑/更新问题并粘贴您用于发送请求和检查响应的确切前端 javascript 代码的 sn-p。 响应的 HTTP 状态码是什么?您可以使用浏览器开发工具中的网络窗格进行检查。是 4xx 还是 5xx 错误而不是 200 OK 成功响应?它是对 CORS preflight OPTIONS 请求的响应吗? 类似于***.com/questions/56759527/… 【参考方案1】:我以这种方式使用它来允许来自所有来源的请求。它适用于我的所有项目。
package com.example.demo.filters;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
@Component
public class CORSFilter extends OncePerRequestFilter
@Override
public void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
final FilterChain filterChain) throws ServletException, IOException
response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
"Origin, Content-Type, Accept, Authorization, Accept-Language, connection, Cache-Control, Access-Control-Request-Method, Access-Control-Request-Headers");
response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD");
response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,
"Access-Control-Allow-Origin, Access-Control-Allow-Credentials");
response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, request.getHeader(HttpHeaders.ORIGIN));
filterChain.doFilter(request, response);
【讨论】:
我没有尝试这个选项,因为 @CrossOrigin 注释本身正在工作。请参阅我的编辑 2。【参考方案2】:我只在应用程序级别配置过 CORS,
但是@CrossOrigin 注释的documentation 表示默认情况下它允许所有来源,因此您可能想尝试
@CrossOrigin()
代替
@CrossOrigin(origins = "*")
文档还说它支持“@RequestMapping 注解中指定的 HTTP 方法”,因此您可能需要在 GET 或 POST 或您当前使用的任何方法之外添加 OPTIONS 方法(CORS 需要支持OPTIONS 方法)。
【讨论】:
@CrossOrigin() 和@CrossOrigin 一样,我试过了。请参阅我的编辑 2。它正在工作,我在观察日志后意识到了这一点。【参考方案3】:您可以在您的 api 端点中使用 @CrossOrigin 而无需提及来源。
指定来源也可能对多层环境造成影响。
【讨论】:
【参考方案4】:请记住,Access-Control-Allow-Origin: *
仅在您没有任何身份验证方法(没有凭据的请求)时使用。见:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源
不要在 fetch 调用中使用 'no-cors'
,因为您会得到 不透明 响应。要么指定'cors'
,要么不指定任何内容。
const response = await fetch("http://localhost:8080",
method: 'GET',
// mode: 'cors',
headers:
'Accept': 'application/json'
);
实际上,当您收到 200 OK
但 opaque
响应时,服务器不再有问题。响应为 200,但数据不透明,因为前端可能设置了“no-cors”或类似设置。见:
https://developers.google.com/web/updates/2015/03/introduction-to-fetch
关于后端,在 Spring Boot(w/Kotlin)中,我使用它来发送
Access-Control-Allow-Origin: *
标头,基于 spring-boot-starter-security
库。
package demo.config
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
@Configuration
class GeneralApiSecurityConfig() : WebSecurityConfigurerAdapter()
override fun configure(http: HttpSecurity)
http.cors()
只要http.cors()
哦,这可能是一条微不足道的建议,但是如果您弄乱了配置,请每次重新启动服务器,否则,您可能正在刷新前端客户端,但服务器正在坚持以前的尝试。
【讨论】:
以上是关于弹簧靴中的 CORS 不起作用 - 得到空响应的主要内容,如果未能解决你的问题,请参考以下文章