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

1.1k 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 answers

1
Jack Murphy 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