Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular $http is sending OPTIONS instead of PUT/POST

I am trying to Update/Insert data in a MySQL database through a PHP backend. I'm building the Front End with AngularJS and using the $http service for communicating with the REST API.

My setup looks like this:

I'm setting the header via the $httpProvider:

 $httpProvider.defaults.withCredentials = true;  $httpProvider.defaults.headers = {'Content-Type': 'application/json;charset=utf-8'}; 

And the POST-Call looks like this:

   return $http({       url: url,       method: "POST",       data: campaign     }); 

The Dev Console in Chrome shows me this:

enter image description here

When I change from POST to PUT, I'm sending an OPTIONS call instead a PUT. And the content-type switches just to content-type.

My request payload is send as an object:

enter image description here

How do I set my header properly?


EDIT:

The PHP backend sets some headers:

   $e->getResponse()               ->getHeaders()               ->addHeaderLine('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');     $e->getResponse()               ->getHeaders()               ->addHeaderLine('Access-Control-Allow-Origin', '*'); 

Is there something missing?

like image 604
ohboy21 Avatar asked May 15 '15 07:05

ohboy21


People also ask

Why is my browser sending an options HTTP request instead of POST?

CORS applies when a webpage makes a request to another server other than its origin server, this could mean that either the domain, protocol, or port differs. Using the request the browser checks with the server whether the request is allowed. Only if the request is allowed, it'll actually perform it.

Can Angular handle post request?

Angular Http POST request with strongly typed response The data returned from the server will have two additional properties like id and createdAt . Using HttpClient. post() method in Angular we can request strongly typed response from the server.

What is request options in Angular?

responseType : ResponseContentType. merge(options?: RequestOptionsArgs) : RequestOptions. Creates a copy of the RequestOptions instance, using the optional input as values to override existing values. This method will not change the values of the instance on which it is being called.

What is the use of HttpClientModule?

The HttpClientModule is a service module provided by Angular that allows us to perform HTTP requests and easily manipulate those requests and their responses. It is called a service module because it only instantiates services and does not export any components, directives or pipes.


2 Answers

Ok, I've solved it.

What was the problem?
The CORS workflow for DELETE, PUT and POST is as follows:

enter image description here

What it does, is:

  1. Checking which request is gonna be made
  2. If it's POST, PUT or DELETE
  3. It sends first an OPTION request to check if the domain, from which the request is sent, is the same as the one from the server.
  4. If not, it wants an Access-Header to be allowed to send this request

Important here: An OPTIONS request doesn't send credentials.

So my backend server disallowed the PUT request.

Solution:
Putting this inside the .htaccess file

RewriteCond %{REQUEST_METHOD} OPTIONS RewriteRule ^(.*)$ blank.php [QSA,L] Header set Access-Control-Allow-Origin "http://sub.domain:3000" Header always set Access-Control-Allow-Credentials "true" Header always set Access-Control-Max-Age "1000" Header always set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding" Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT" 

After this, create an empty .php file called blank.php inside the public folder.

EDIT: As one commenter pointed out, instead of creating an empty PHP file, you can add this rewrite rule to your .htaccess file\;

RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}]] 

To clarify:

  1. I already sent the Access-Control-Header
  2. What it solved was the first two lines, and
  3. Access-Control-Allow-Origin from the specific subdomain with Port

Best website I could find to learn more about CORS.

like image 137
ohboy21 Avatar answered Sep 23 '22 02:09

ohboy21


You don't need to specify your $http headers manually, it is all done for you behind the scenes and they are automatically set to application/json for POST and PUT type requests. So all that you should do is

$http.post(url, data); $http.put(url, data); 
like image 22
Dan Moldovan Avatar answered Sep 24 '22 02:09

Dan Moldovan