【发布时间】:2019-02-18 18:55:14
【问题描述】:
我的代码遇到 CORS 错误时遇到问题。如果我使用 --disable-web-security 从 chrome 实例运行该代码,则该代码有效。 我的 Spring ApplicationConfig 中有以下代码:
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*").allowedMethods("*").allowedHeaders("*");
}
};
}
当我的前端提交其 OPTIONS 请求成功时,状态为 200 并且响应具有以下标头:
Request URL: http://127.0.0.1:9000/oe/Auth/login
Request Method: OPTIONS
Status Code: 200 OK
Remote Address: 127.0.0.1:9000
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, X-Requested-With
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT, PATCH
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3600
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 0
Date: Fri, 14 Sep 2018 01:27:15 GMT
Expires: 0
Pragma: no-cache
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
当它提交 POST 以登录时,我收到以下控制台错误:
Failed to load http://127.0.0.1:9000/oe/Auth/login:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:3000' is therefore not allowed access.
这是网络标签
Request URL: http://127.0.0.1:9000/oe/Auth/login
Request Method: POST
Status Code: 200 OK
Remote Address: 127.0.0.1:9000
Referrer Policy: no-referrer-when-downgrade
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Date: Mon, 17 Sep 2018 20:19:48 GMT
Expires: 0
Pragma: no-cache
Server: Apache-Coyote/1.1
Set-Cookie: SESSION=ZjlhYTE5NmMtNDk3NC00Yzc4LTk1MDYtN2FjNzBhMjFhMGI0; Path=/oe/; HttpOnly
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
这是因为 Spring Security 在我的 CorsRegistration 发生问题之前就抓住了这个请求吗?
【问题讨论】:
-
响应的 HTTP 状态代码为 500
-
如果你的意思是它不是一个 cors 问题,它实际上是一个内部服务器错误,那不是问题。根据访问日志,第二个请求甚至从未到达服务器,它被浏览器阻止,因为错误语句暗示了关于 Access-Control-Allow-Origin 的第一部分
-
如果浏览器收到对 CORS 预检 OPTIONS 的 500 响应,则 CORS 协议要求浏览器在此处停止,而不是尝试从您的代码发送 POST。这就是浏览器发送 OPTIONS 的全部目的:从服务器上查明是否可以继续。为了让浏览器决定可以继续,它需要看到对该 OPTIONS 的 200 OK 成功响应,而不是 500。因此,即使该 500 响应包含 Access-Control-Allow-Origin 标头,您的请求仍然会失败—因为预检仍然会失败,因为响应代码不是 200 OK
-
选项请求成功我更新了上面的文本以更清楚地说明失败的是帖子请求,并且帖子上的响应标头不包含选项请求拥有的任何标头。我认为这实际上更像是一个 Spring 和 Spring 安全问题。我最好的猜测是 spring-security 在 CORS 注册用于设置标头之前拦截了发布请求。
-
是的,这很可能是在您的应用程序代码运行之前,服务器系统中出现了 500 的原因。但无论如何,大多数服务器默认情况下不会将标头添加到 5xx 和 4xx 错误响应中——相反,它们只是将它们添加到 2xx 响应中,也许还会添加到 3xx 响应中。要让服务器向错误响应添加标头,您通常需要添加一些非默认配置。例如,对于 nginx 和 Apache,您需要在设置标头的指令中添加“always”参数。
标签: spring-mvc tomcat spring-security axios