Why does Angular send Http Request Method: Options before POST?

1.2k Views Asked by At

I'm using Angular Dart V1 for a front end framework I am using shelf && shelf router for a backend API

I'm trying to migrate some old get requests to accept Post Data

Old request:

Future fetchRoutes(FlightPostParamsVO params) async {
  return _http.get(BASE + 'routes').then(handleRoutes);
}

New Request

Future fetchRoutes(FlightPostParamsVO params) async {
    Map post = params.toPostable();
    return _http.post(BASE + 'routes', post ).then(handleRoutes);
  }

I'm setting the CORS headers in a generic response for all calls as its strictly a JSON API:

Future<Response> makeResponse( json ) async {
  var response = new Response.ok( json, headers: {'content-type': 'text/json',
                                                  'Access-Control-Allow-Origin': '*',
                                                  'Access-Control-Allow-Headers': "Origin, X-Requested-With, Content-Type, Accept",
                                                  'Access-Control-Allow-Methods': "POST, GET, OPTIONS"} );
  return response;
}

I get a 404 an the following output:

OPTIONS http://localhost:1234/tickets/routes 404 (Not Found)
(index):1 XMLHttpRequest cannot load http://localhost:1234/tickets/routes. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 404.

When i inspect the network traffic - all my GET request DO HAVE the correct headers

When i inspect the network traffic - my POST call is lead bya request with a method set as OPTIONS - this call does not have the headers included.

My POST route handler never gets called

Router

  Router airRouter = router();

  Router tickets = airRouter.child('/tickets');
  tickets.add('/cities', ['GET'], controller.handleCitites);
  tickets.add('/times', ['GET'], controller.handleTimes);
  tickets.add('/routes', ['POST'], controller.handleRoutes);
  tickets.add('/{id}/tickets/', ['GET'], controller.handleTickets);

  io.serve(airRouter.handler, 'localhost', 1234);

Fix Symptom:

tickets.add('/routes', ['OPTIONS'], controller.handleRoutes);

Question: Why is the HTTP Request sending a Request Method:OPTIONS before each POST, and whats the proper way only call POST?

1

There are 1 best solutions below

1
On

That is not angular. Its the browser. The first request of method OPTION is to test for CORS header to make sure the browser is allowed to post.

Solution:

http://thomaslockerambling.blogspot.com/2014/10/shelf-middleware-adding-cors-headers.html

  • Create a CORS Object and append to header
  • Intercept an Call to OPTIONS
  • Response with status code 200 OK