1

I have a strange issue with sending POST request to my Node.js server. I have also some GET listeners but they work perfectly fine. So, I am trying to send a simple request from Angular 2 application (port 4200) to Node.js server (port 443) as followed but I receive an error:

XMLHttpRequest cannot load http://localhost:443/edit_comment. 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.

Client service method:

   public saveComment(id: number, comment: string) : Observable<Response> {
        let data         = { id: id, comment: comment };
        let headers      = new Headers({'Content-Type': 'application/json'}); 
        let options      = new RequestOptions({ headers: headers });


        return this.http.post('http://localhost:443/edit_comment', JSON.stringify(data), options)
            .map((res:Response) => res.json())
            .catch((error:any) => Observable.throw(error.json().error || 'Server error')); 
    }

and node.js server side (with express library):

app.post('/edit_comment', (req, resp) => {
    console.log('blabla') //this log never displays
    resp.setHeader('Access-Control-Allow-Origin','*')
    resp.send(JSON.stringify('foo'))
});

The problem is that it seems that app.post callback function is not even called because console.log does not display 'blabla' message on screen.

Here you have also Request and Response headers from developer tools in my browser:

Request Headers:

Accept:*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Cache-Control:no-cache
Connection:keep-alive
Host:localhost:443
Origin:http://localhost:4200
Pragma:no-cache
Referer:http://localhost:4200/testlinemonitor
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36

Response Headers:

HTTP/1.1 200 OK
X-Powered-By: Express
Allow: POST
Content-Type: text/html; charset=utf-8
Content-Length: 4
ETag: W/"4-oCQ57CKdi+DnSwwWAjkjEA"
Date: Fri, 10 Mar 2017 12:49:41 GMT
Connection: keep-alive

Regards

Michal Bialek
  • 499
  • 1
  • 10
  • 26
  • Preflight request OPTIONS /edit_comment should be configured for sending proper headers as before calling POST /edit_comment the browser will call OPTIONS /edit_comment – Manan Vaghasiya Mar 10 '17 at 13:05
  • Possible duplicate of ["No 'Access-Control-Allow-Origin' header is present on the requested resource"](http://stackoverflow.com/questions/20035101/no-access-control-allow-origin-header-is-present-on-the-requested-resource) – georgeawg Mar 10 '17 at 13:22

2 Answers2

2

You backend is not able to respond for OPTIONS call. If you have cross origin requests, the browser always does preflight OPTIONS call. And then if successful, it does GET or POST. Please check network traffic in Chrome Debugger.

This is package for ExpressJS server https://github.com/expressjs/cors

Łukasz
  • 623
  • 5
  • 12
  • I installed cors and now my request is "catched" by app.post but how to get to POST params? req.body is empty – Michal Bialek Mar 10 '17 at 13:11
  • Backend has to be able to return proper access control headers for OPTIONS call. Check the last piece of code here http://johnzhang.io/options-request-in-express or use the middleware package from expressjs/cors – Łukasz Mar 10 '17 at 13:11
  • Ok but now I have a problem with getting POST params. It seems that they are not sent or smth. Req.body is an empty dictionary – Michal Bialek Mar 10 '17 at 13:17
  • Firstly, open Chrome DevTools and check if you're sending them https://developers.google.com/web/tools/chrome-devtools/network-performance/reference – Łukasz Mar 10 '17 at 13:24
  • I have something like "Request Payload" with my object below Response and Request headers – Michal Bialek Mar 10 '17 at 13:26
0

You need to allow not only your allowed origins, but also allowed methods and headers.

Try adding this headers that allow CORS requests:

res.setHeader('Access-Control-Allow-Origin', '*')

//Add as many Headers as you want to line below
//If you use "Authentication" Header, insert it like 'Content-type, Authentication'
res.setHeader('Access-Control-Allow-Headers', 'Content-type')

res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
Matheus Martins
  • 1,012
  • 7
  • 7
  • Did you read my code? :) I had Access-Control-Allow-Origin header set. I even added the rest of headers you provided but it does not work – Michal Bialek Mar 10 '17 at 13:06