When I send a POST request to the server I get an error:
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:
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:
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.
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.
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 :
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");
You need to ensure that the Spring accept CORS requests
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With