4

I have an Angular app (v1.13.15) and Express.js(v4.12.4) as backend.

I have a DELETE method in my backend, and I have enabled CORS support for it.

But, when I use Angular $http.delete, I run into this error

No 'Access-Control-Allow-Origin' header is present on the requested resource.

I have tried using Jquery, $.ajax() call for it, and I get the same problem!

I also tried using POSTMAN to do a DELETE request and there is no problem.

But, I have no problem accessing using my Angular for my GET and POST method..

May I know what is this problem?

My backend URL http://localhost:3000

I serving my AngularJS using gulp-webserver http://localhost:8000

My server code

exports.deleteGPSData = (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

let id = req.params.id;

res.send('here');
}

and my Angular code

$http.delete(API_URL + '/gps/' + id)
                .success(function(res) {
                    if (res.result !== 1) {
                        return defer.reject(new Error(id + ' failed to delete'));
                    }

                    defer.resolve(res.id);
                })
                .error(function(status) {
                    defer.reject(status);
                });

I have no problem with GET and POST method! only when I use DELETE method, I ran into CORS errors!

I have attached a screenshot below for the request header using Google Chrome

Angular CORs problme

Below is the screenshot from Postman,

POSTMAN delete

Tim
  • 3,755
  • 3
  • 36
  • 57
  • Try changing `res.header('Access-Control-Allow-Headers', 'X-Requested-With,content-type');` to `res.header('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type');` and let me know if this changes anything. – Blue May 28 '15 at 04:51
  • Can you post your express code also? – Neo May 28 '15 at 04:54
  • @FrankerZ I changed, but the same problem occurs. – Tim May 28 '15 at 04:55
  • @neolivz4ever which part do you want? I posted the router middleware in this post already, if you want before the middleware then it is just app.delete('/gps/:id', routes.gps.deleteGPSData); – Tim May 28 '15 at 04:55
  • @FrankerZ updated with screenshot from postman – Tim May 28 '15 at 05:04
  • Try adding `,accept` to the `Access-Control-Allow-Headers`. You can read about how to basically wildcard all headers [here](http://stackoverflow.com/a/13147554/4875631). I believe this is where your issue is. – Blue May 28 '15 at 05:04
  • @FrankerZ thanks!, i did that but it doesnt work, managed to find that problem, answer below! :) – Tim May 28 '15 at 05:16

5 Answers5

8

I managed to solve this problem, it is due to preflight request

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

When doing CORS for DELETE, it will first send an OPTIONS method to the server, and then it will resolve to DELETE method

So it in backend, I should have route for OPTIONS and then call next() to pass it to DELETE method

Backend code:

app.options('/gps/:id', routes.gps.optionGPSData);
app.delete('/gps/:id', routes.gps.deleteGPSData);

and my router middleware

exports.optionGPSData = (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type');

next();
}

POSTMAN is able to perform a DELETE request? (this is because it sends a DELETE http request to my server, and not OPTIONS) whereas in web browser, it will send an OPTIONS for preflight request (this is mainly for security concern)

*shoutout to @FrankerZ, he enlights me to compare POSTMAN and my Chrome result, and then I see there is a difference in Access Control Allow Method, which leads me to try cors middleware (https://www.npmjs.com/package/cors), and it works and then I managed to pin the problem and is due to the preflight request!

Tim
  • 3,755
  • 3
  • 36
  • 57
0

you can use the cors npm module to enable cros domain request

https://www.npmjs.com/package/cors

HDK
  • 816
  • 1
  • 8
  • 13
0
app.options('/gps/:id', function(req, res) { res.json({}) });
app.delete('/gps/:id', routes.gps.optionGPSData);

you can define your own options callback(need not to be same).

Thaillie
  • 1,362
  • 3
  • 17
  • 31
0

preflight request only sends the headers and not the header values. Hence , this causes issue.

CORS needs to be handled from both client and server side.

I have added below header settings in server.js file(application is in reactjs)

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Request-Headers", "*");
  res.header('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With,X-HTTP-Method-Override, Content-Type, Accept, Authorization");
  res.header("Access-Control-Allow-Credentials", "true");
  next();
});

From sever side as well we had to handle CORS request.

Below is the changes done in server side API(application is in java jersey framework)

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Request-Headers", "*");
  res.header('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With,X-HTTP-Method-Override, Content-Type, Accept, Authorization");
  res.header("Access-Control-Allow-Credentials", "true");
  next();
});

This preflight issue occurs only whne we try to connect to localhost from different origin.

Shruthi S
  • 29
  • 2
-1

As for me I spent half a day searching for a suitable solution for the Angular / MangoDB combination, but failed. So, I have found one workaround by using the Google extension CORS-Unblock (Unblock CORS error while developing or experimenting) and it worked like a charm. Hope it helps somebody.

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 07 '22 at 16:23