2

I am using dart on my server and angulardart as my client. I can request data via http.get on my server, that is working fine - but I can't get POST to work.

Server: (the server makes use of "Start" https://github.com/lvivski/start)

//runs at 127.0.0.1:4040:
server.post("/rest/qr").listen((request) {
  addCorsHeaders(request.response);
  request.payload().then((map) {
    print(map);
  }).then((_) {
    request.response.send("ok");
  });
});

Client (angular):

// runs at http://127.0.0.1:3030
final String _codesUrl = "http://127.0.0.1:4040/rest/qr";
_http.post(_codesUrl, JSON.encode(temp.toMap())).then((HttpResponse response) {
  print(response.status);
});

addCorsHeaders:

void addCorsHeaders(Response res) {
    res.header("Access-Control-Allow-Origin", "*, ");
    res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");}

This is my code. As I already said, http.get from angular to my server does work. Post to my server via the angular http-service fail : "No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '127.0.0.1:3030' is therefore not allowed access."

I also tried the advanced rest plugin in Google Chrome to make POST-request to that URL.These requests do work. Do I miss something on the angulardart POST-requests? Server and Client run on different ports.

Schnebdreleg
  • 77
  • 11
  • I used this a while ago to access a server written in Go and I had troubles to get it to work with `-Allow-Origin", "*, "` I used `"http://127.0.0.1:3030"` instead. Did you verify if the CORS request reaches your server? – Günter Zöchbauer May 28 '14 at 15:41
  • @GünterZöchbauer I already tried to put the IP of the client into the origin field. That also failed. I can see the client sending the POST-request, but its like the request does not reach the server at all. Funny thing is, I can do request via other programs to the server. Ty for the fast answer btw. – Schnebdreleg May 28 '14 at 15:46
  • Shouldn't you use the full URL in your post request? I assume your server uses a different port than the DartEditor integrated server that serves your client application? – Günter Zöchbauer May 28 '14 at 15:51
  • @GünterZöchbauer you are right. It's a different port for client/server. The URL for the request is "_codesUrl = "http://127.0.0.1:4040/rest/qr";" The advanced rest client also shows the CORS-headers i've set in the server. – Schnebdreleg May 28 '14 at 15:55
  • But the code in your question doesn't show this. Can you please update the question. – Günter Zöchbauer May 28 '14 at 15:56
  • When you tried the IP of the client, did you also have the `, ` at the end of the `Allow-Origin` value? I remember that this caused me troubles but this is over 1/2 year ago so I don't remember properly. Can you try to ensure that the CORS headers are added when the client requests `http://127.0.0.1:4040` without `/rest/qr` I think I remember that the CORS request was maid to the root URL. – Günter Zöchbauer May 28 '14 at 16:03
  • @GünterZöchbauer this is getting kind of frustrating right now. I tried with and without the ",". When I alter the addCorsHeader-method to something silly, the http.get-requests do not work anymore, so the method seems to work. Its like the POST-request does not find the URL. When I alter server.post to server.get (and in the client also), the requests get through. I also added the CORS-headers to the root-dir now, still the same problem. – Schnebdreleg May 28 '14 at 16:24
  • I understand that, I wasted many hours the first time ... Do the Dartium devtools provide any information about if the request was made and how it exactly looked like? – Günter Zöchbauer May 28 '14 at 16:27
  • @GünterZöchbauer thank you for your effort in helping me with this case! – Schnebdreleg May 28 '14 at 16:47

1 Answers1

2

I've run into this issue myself. Turns out that some CORS requests require a "preflight request". GET does not, but POST does. The following article explains all of this in detail:

http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server

The gist is that for a POST CORS request, the client will first send an "OPTIONS" request to the server, asking if a CORS POST is OK or not. This is the "preflight request" I mentioned previously. You need to catch it and respond back to it before you will get the POST.

I'm not sure how to answer OPTIONS requests with the Start framework, but the dartlang website has a tutorial on how to solve the exact problem with vanilla dart:

https://www.dartlang.org/docs/tutorials/forms/#handling-options-requests

The code to handle the OPTION requests (cribbed from the above article):

void handleOptions(HttpRequest req) {
  HttpResponse res = req.response;
  addCorsHeaders(res);
  print('${req.method}: ${req.uri.path}');
  res.statusCode = HttpStatus.NO_CONTENT;
  res.close();
 }
Greg Sherman
  • 1,084
  • 1
  • 11
  • 22
  • you are my hero today! I didn't read all of this article you provided before, but this was exactly my problem! I've added a OPTIONS to "/rest/qr" with an empty response with status "200" and now my angular client can POST data to that URL. – Schnebdreleg May 28 '14 at 16:44
  • @Schnebdreleg but that means that you must have received the CORS (preflight) request on your server already before you added "OPTIONS". – Günter Zöchbauer May 28 '14 at 16:48
  • @GünterZöchbauer yes, seems like it, but I couldn't see it. With the Start-Framework I was only listening on certain URLs with specified methods. The debugger wasn't very helpful when I searched for the requests of the angular http-service ( or I didn't know where to search, I am still learning Dart :) ) – Schnebdreleg May 28 '14 at 16:54
  • No prob, just to understand what was going on. Thanks for your response. – Günter Zöchbauer May 28 '14 at 16:56