6

Im stuck at this 2 days I can not find a solution. When im doing an AngularJS POST it Sends OPTIONS in the header and returns error from the API the code looks like this nothing special.

$http.defaults.headers.post["Content-Type"] = "application/json";
$http.post(URL, JSON.stringify(data)).
    success(function(data, status, headers, config) {
        alert(data);
    error(function(data, status, headers, config) {
        console.log("Error");
});

CORS is enabled on the API it has the Headers, when i do POST with fiddler or POSTMan in Chrome it works fine only when i use angularJS post it won't go thru.

why do i get OPTIONS /SubmitTicket HTTP/1.1 instead of POST?

What do i need to do to POST ? I have read about it it says something like CORS is adding OPTIONS header but why?

Eylen
  • 2,457
  • 3
  • 24
  • 42
AlCode
  • 545
  • 1
  • 7
  • 21
  • try using $http.put – Shian JA Jun 08 '15 at 08:25
  • @Mico Sends OPTIONS again.. – AlCode Jun 08 '15 at 08:28
  • The HTTP methods POST and PUT aren't the HTTP equivalent of the CRUD's create and update. They both serve a different purpose. It's quite possible, valid and even preferred in some occasions, to use POST to create resources, or use PUT to update resources. – Shian JA Jun 08 '15 at 08:30
  • @Mico I just want to send JSON object and get a JSON object in return.. :/ – AlCode Jun 08 '15 at 08:31
  • 4
    Don't stringify the data... Angular does that for you!! `$http.post(URL, JSON.stringify(data)).` should be `$http.post(URL, data).` and don't set the `Content-Type`, angular also does this for you... – Callum Linington Jun 08 '15 at 08:32
  • @CallumLinington fully Agreed. For more Please See the Example Below in my answer – Shian JA Jun 08 '15 at 08:37
  • @Orom I think that you have a typo in your code, The success function is not closed – Eylen Jun 08 '15 at 08:56
  • @Eylen how i wish that was the error.. as I copy pasted the code i forgot to add } sorry – AlCode Jun 08 '15 at 09:01
  • @Orom, OPTIONS request is triggered by some custom header. Most of the time it is "X-Requested-With": "XMLHttpRequest" header. Can you list all headers from your POST request? – Maksym Demidas Jun 08 '15 at 09:33
  • @MaksymDemidas Indeed it is because of application/json i think, that triggers the OPTIONS. But the API only accepts JSON, so i changed the Content-Type to "application/x-www-form-urlencoded which resulted in a "Not found" error.. – AlCode Jun 08 '15 at 10:20

4 Answers4

2

When you invoke the CORS requests, the browser always sends the OPTIONS request to server to know what methods are actually allowed. So this is the desired behaviour. This is so called: "Preflighted request", see: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/ (section: "Preflighted requests")

Therefore in your case, you have to allow the OPTIONS method in 'Access-Control-Allow-Methods' header of your CORS filter.

Thomas Weglinski
  • 1,054
  • 1
  • 10
  • 21
  • I have this in my API web config: Is this enough? – AlCode Jun 08 '15 at 08:51
  • It might be. Be aware that from the security point of view, you have to enable only this options that are you actually using in your API. I usually have GET, PUT, POST and of course OPTIONS. – Thomas Weglinski Jun 08 '15 at 08:54
1

My understanding is that angular initially sends an OPTIONS request to the server in order to ask the server if the full request is permissable. The server will then respond with Headers specifying what is and is not allowed.

I guess this might be an issue with the server returning the wrong CORS headers. You said that the server returns an error please post that error here.

See Preflighted CORS request at: http://www.staticapps.org/articles/cross-domain-requests-with-cors and AngularJS performs an OPTIONS HTTP request for a cross-origin resource

Community
  • 1
  • 1
Kiachma
  • 11
  • 3
  • It only says Error 500, "Server Error Occured" how do i handle the OPTIONS request? that is something i don't get.. – AlCode Jun 08 '15 at 08:48
  • Make sure the API returns the following header 'Access-Control-Allow-Origin: *' (to accept CORS from all sources) or 'Access-Control-Allow-Origin: the address of your client' – Kiachma Jun 08 '15 at 08:54
  • indeed i have that too: – AlCode Jun 08 '15 at 08:55
  • I had similar problems setting up a go backend API and angular. The solution was to bypass the default request router and dispatcher for OPTION requests. These where the headers i ended up returning Access-Control-Allow-Origin : Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE Access-Control-Allow-Headers: Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization – Kiachma Jun 08 '15 at 09:11
  • Just aded thes to the API Web Config? – AlCode Jun 08 '15 at 09:16
  • Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Content-Length,Accept-Encoding,X-CSRF-Token,Authorization Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD, OPTIONS Still not working, what does your Request header say application/json? or? – AlCode Jun 08 '15 at 09:19
  • Change origin with the address of your requests origin. This is not really related with Angular anymore, so I guess you're better of googling " preflighted CORS" and maybe start a new question with proper tags. – Kiachma Jun 08 '15 at 09:52
0

// Simple POST request example (passing data) :

$http.post('/someUrl', {msg:'hello word!'}).
  success(function(data, status, headers, config) {
    // this callback will be called asynchronously
    // when the response is available
  }).
  error(function(data, status, headers, config) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
  });
Shian JA
  • 818
  • 3
  • 14
  • 52
0

Should only need to do this code to get it to work:

angular.module('TestApp', [])
   .factory('someService', ['$http', someService]);

function someService() {
  var service = {
    save: save
  };

  var serviceUrl = '/some/Url';

  return service;

  function save(data) {
    $http.post(serviceUrl, data)
          .success(function(data, status, headers, config) {
              alert(data);
          })
          .error(function(data, status, headers, config) {
              console.log("Error");
          });
  }
}

Then pull your someService into your controller and use:

someService.save(data);
Callum Linington
  • 13,082
  • 10
  • 61
  • 132