1

Frontend: Angular5

Backend: Java (Running on a Wildfly 8.x server)

On making an HTTP POST request with content-type: 'application/json' from my Angular application to the server, I get the following error:

Failed to load http://localhost:8080/myk/api/v1/events/addevent: 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.

This is the code for the request:

const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; this.http.post("http://localhost:8080/myk/api/v1/events/addevent", jsonPayload, httpOptions).subscribe();

On inspecting, I found that instead of a POST request, an OPTIONS request was being made (as in accordance with this MDN article on CORS and preflighted requests).

However, when I tried the same request using Postman, it worked perfectly fine.

How does Postman not face an issue with the OPTIONS request when I'm not handling the OPTIONS request at the server?

Also, what can I do (while maintaining the same content-type and without having to modify the server side code) to solve this issue?

Note 1: Although this question addresses the same issue, the suggested solution requires changing the content-type.

Note 2: When I run another application (designed, not by me, in Angularjs) which attempts to make a POST request using an ajax call, it works fine. (I do not understand why this works and, besides, an answer related to angular5 would be appreciated. I included this note in case it helps in figuring out the problem with the Angular5 application)

EDIT: This might be bordering on fussy, but I'm specifically looking to try to solve the above by modifying client side code and not by using extensions or any modifications related to the browser. However, if none of that is possible, I'm open to changing server-side code.

rahs
  • 1,759
  • 2
  • 15
  • 31
  • if you don't pass the headers, you won't get the OPTIONS call – Milad Mar 19 '18 at 10:52
  • In that case how do i specify that the data being sent is JSON? Also, in Postman, I have included a header indicating content type as application/json (while choosing raw data as the body type) and it still works – rahs Mar 19 '18 at 11:00
  • you better accept the header in your backend code anyway, it's just one line of code. You can't get away with not taking care of COREs – Milad Mar 19 '18 at 11:12
  • `@RequestMapping(value="/addevent",method=RequestMethod.POST,produces=org.springframework.http.MediaType.APPLICATION_JSON_VALUE) public ResponseEntity> addNewEvent( @RequestBody EventDTO event,HttpServletRequest request)` This is my current server side code's method'd signature. How is Postman still able to successfully access it and get JSON data across to the server? – rahs Mar 19 '18 at 11:17
  • "However, if none of that is possible, I'm open to changing server-side code." — You need to modify the server side code. It would be stupid if your client side could disable a security feature designed to stop your client side code from accessing other sites. – Quentin Mar 19 '18 at 11:37
  • Okay. How can i accept option requests on the client side? (Considering that you're saying that the answer given is insufficient) – rahs Mar 19 '18 at 13:15

2 Answers2

0

This issue is known as CORS. Cross Origin Resource Sharing. This is arises when the origin of the request and response is different. For example: If your project is on https://139.43.33.122:1111/ and your server is hosted on https://123.0.3.444:3000, then the origin of your request and response are completely different and thus, browser will block the response. This is the browser thing. Postman doesn't care about their origin. To receive response, there are 2 ways (maybe more but i use these 2 only).

  1. Additional Headers: If yoou have access/permission to server code, then add an additional header to the server responses: Access-Control-Allow-Origin: http://siteA.com, Access-Control-Allow-Methods: GET, POST, PUT, Access-Control-Allow-Headers: Content-Type.

  2. Use Extensions: There are multiple extensions that can bypass this restriction. IF you do not have access or permission to change the server response, then this is the way to go.I'm personally using this method only.

Shadab Faiz
  • 2,380
  • 1
  • 18
  • 28
  • "Access-Control-Allow-Origin: *" — It's a preflighted request. That is insufficient. – Quentin Mar 19 '18 at 11:28
  • "Use Extensions" — This is a hack for use during dev, and utterly impractical during production. – Quentin Mar 19 '18 at 11:28
  • Thanks. I had previously tried using the CORS extension for Chrome, but it didnt seem to make a difference. There is nothing to be done after installing and switching on the extension, right (from what I saw, its only functionality seemed toggling it on and off)? – rahs Mar 19 '18 at 11:31
  • @Quentin Agreed about the extensions. I should've mentioned that in my question – rahs Mar 19 '18 at 11:32
  • @Quentin Thanks for reminding, i almost forgot the access control part and yes, extension is a dev hack. – Shadab Faiz Mar 19 '18 at 11:37
  • @RahulSaha this is the extension which i use:https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi. Sometimes you may need to toggle it 2-3 times to work but remember, as Quentin mentioned: this is just a dev hack. It is ok only if your project and server will hosted on the same origin. If not, then dont use it. It wont solve your problem as every user will need to have this extension installed on their system. – Shadab Faiz Mar 19 '18 at 11:41
0

I had the same issue and I have found a trick to avoid both CORS and 403 error thanks to this article.

  1. Add Postman Interceptor on your Google Chrome : https://chrome.google.com/webstore/detail/postman-interceptor/aicmkgpgakddgnaphhhpliifpcfhicfo/support?hl=en

  2. Activate Postman Interceptor in Postman

enter image description here

  1. Launch your request and capture the cookie thanks to Postman interface

enter image description here

  1. Open your Chrome development tool, go to the console and add manually the cookie found thanks to postman interceptor

    document.cookie="keyofcookie=valueofcookie"

enter image description here

Retry your request, it works !

Otherwise, just to avoid CORS, you can use the proxy described here.

orion_nemo
  • 71
  • 6
  • Thanks, but isn't this a browser fix that each user will have to do individually? – rahs Mar 22 '18 at 14:36
  • Unfortunately, you're right. It is a really dirty solution. However, you can customize the cookie, make it timeless [https://developer.mozilla.org/fr/docs/Web/API/Document/cookie] and push it at the beginning of each user session. It is the only solution that I found. – orion_nemo Mar 22 '18 at 14:48
  • LOL, you need to tell all your users to install interceptor to their browser LOLOLOOLOLOLOLOL – Jhourlad Estrella Jun 18 '19 at 12:54