java Angular 5:预检响应具有无效的 HTTP 状态代码 403
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49801424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular 5: Response for preflight has invalid HTTP status code 403
提问by Vitaliy Pogoretsky
When I send a POST request to the server I get an error:
当我向服务器发送 POST 请求时,出现错误:
Failed to load http://localhost:8181/test: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 403.
The backend is written in Java Spring. My method for creating a test:
后端是用 Java Spring 编写的。我创建测试的方法:
createTest() {
const body = JSON.stringify({
'description': 'grtogjoritjhio',
'passingTime': 30,
'title': 'hoijyhoit'
});
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Accept': 'application/json'
}
)
};
return this._http.post(`${this._config.API_URLS.test}`, body, httpOptions)
.subscribe(res => {
console.log(res );
}, error => {
console.log(error);
});
}
Get Method works, but Post doesn't. They both work in Swagger and Postman. I changed POST method many times. The headers in my code do not work, but I solved the problem with them expanding to Google Chrome. There was only an error:
Get 方法有效,但 Post 无效。他们都在 Swagger 和 Postman 工作。我多次更改 POST 方法。我的代码中的标头不起作用,但我解决了将它们扩展到 Google Chrome 的问题。只有一个错误:
Response for preflight has invalid HTTP status code 403.
It seems to me that this is not Angular problem. Please tell me how I or my friend (who wrote the backend) can solve this problem.
在我看来,这不是 Angular 问题。请告诉我我或我的朋友(编写后端)如何解决这个问题。
回答by Raj Rajeshwar Singh Rathore
PROBLEM :
问题 :
For any Cross-Origin POST request, the browser will first try to do a OPTIONS call and if and only if that call is successful, it will do the real POST call. But in your case, the OPTIONS call fails because there is no 'Access-Control-Allow-Origin'
response header. And hence the actual call will not be done.
对于任何跨域 POST 请求,浏览器将首先尝试执行 OPTIONS 调用,并且当且仅当该调用成功时,它才会执行真正的 POST 调用。但在您的情况下, OPTIONS 调用失败,因为没有 'Access-Control-Allow-Origin'
响应标头。因此,不会进行实际的调用。
SLOUTION :
懒惰:
So for this to work you need to add CORS Configuration on the server side to set the appropriate headers needed for the Cross-Origin request like :
因此,为此,您需要在服务器端添加 CORS 配置以设置跨源请求所需的适当标头,例如:
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers", "content-type, if-none-match");
response.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers", "content-type, if-none-match");
response.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Max-Age", "3600");
回答by Ahmed Elkoussy
You need to ensure that the Spring accept CORS requests
您需要确保 Spring 接受 CORS 请求
Also if you have applied Spring security & require authorization headers for example for your API, then (only if you need to make your app support CORS)you should exclude the OPTIONS calls from authorization in your spring security configuration file.
此外,如果您已经为 API 应用了 Spring 安全性和需要授权标头,那么(仅当您需要使您的应用程序支持 CORS 时)您应该在您的 spring 安全性配置文件中从授权中排除 OPTIONS 调用。
It will be something like this:
它会是这样的:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
@Override
public void configure(WebSecurity web) throws Exception {
// Allow OPTIONS calls to be accessed without authentication
web.ignoring()
.antMatchers(HttpMethod.OPTIONS,"/**")
Note:
笔记:
In production, probably it is better to use reverse proxy (like nginx) & not allow the browsers to call your API directly, in that case, you don't need to allow the OPTIONS calls as shown above.
在生产中,最好使用反向代理(如 nginx)并且不允许浏览器直接调用您的 API,在这种情况下,您不需要允许 OPTIONS 调用,如上所示。
回答by Klimiuk S
I've had the exact same problem with Angular lately. It happens because some requests are triggering preflight requests eg. PATCH
, DELETE
, OPTIONS
etc. This is a security feature in web browsers. It works from Swagger and Postman simply because they don't implement such a feature. To enable CORS requests in Spring you have to create a bean that returns WebMvcConfigurer
object. Don't forget of @Configuration
in case you made an extra class for this.
我最近在 Angular 上遇到了完全相同的问题。发生这种情况是因为某些请求正在触发预检请求,例如。PATCH
,DELETE
,OPTIONS
等,这是在Web浏览器安全功能。Swagger 和 Postman 之所以能使用它,只是因为他们没有实现这样的功能。要在 Spring 中启用 CORS 请求,您必须创建一个返回WebMvcConfigurer
对象的 bean 。不要忘记,@Configuration
以防万一你为此做了一个额外的课程。
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
.allowedHeaders("*");
}
};
}
Of course, you can tune this up to your needs.
当然,您可以根据自己的需要进行调整。