Issues with Cross-origin resource sharing (CORS) arise when attempting to delete data using Angular

I am facing an issue with my Angular app (v1.13.15) and Express.js(v4.12.4) backend.

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

However, every time I attempt to use the Angular $http.delete function, I encounter the following error:

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

Even after trying alternatives like Jquery's $.ajax() method, the problem persists!

Interestingly, when using POSTMAN for a DELETE request everything works fine.

Strangely enough, accessing my backend via Angular for GET and POST methods poses no issues.

I am seeking assistance to diagnose and resolve this perplexing problem.

This is my backend URL: http://localhost:3000

And I serve my AngularJS application using gulp-webserver at: http://localhost:8000

The snippet from 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');
}

As for my Angular implementation:

$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);
                });

The peculiarity here is that only my DELETE method encounters CORS errors, while the GET and POST methods work flawlessly!

For reference, I have included a screenshot of the request header using Google Chrome below.

Furthermore, here is the Postman screenshot for comparison:

Answer №1

I successfully resolved the issue at hand, which turned out to be related to preflight requests.

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

When implementing CORS for DELETE requests, an OPTIONS method is first sent to the server, followed by the actual DELETE method.

In the backend, I needed a route for OPTIONS in addition to passing it to the DELETE method.

Here's how the backend code looks:

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

Furthermore, 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();
}

While POSTMAN was able to execute a DELETE request without any issues, the web browser sends an OPTIONS preflight request due to security concerns.

Special thanks to @FrankerZ for prompting me to compare the results between POSTMAN and Chrome, leading to the discovery of a discrepancy in Access Control Allow Method. This ultimately led me to try using the cors middleware (https://www.npmjs.com/package/cors), which helped identify and resolve the preflight request problem!

Answer №3

app.options('/location/:id', function(req, res) { res.json({}) });
app.delete('/location/:id', routes.location.deleteLocation);

Feel free to create your own options callback that does not necessarily have to be identical.

Answer №4

When making a preflight request, only the headers are sent without their values, which can cause issues.

CORS (Cross-Origin Resource Sharing) needs to be managed from both the client and server sides.

In my server.js file (built with ReactJS), I have included the following header settings:

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();
});

We also had to handle CORS requests on the server side in our API built with 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 specifically arises when trying to connect to localhost from a different origin.

Answer №5

After spending countless hours searching for a solution to the Angular / MangoDB compatibility issue, I finally stumbled upon a workaround that saved the day. By utilizing the Google extension CORS-Unblock (Unblock CORS error while developing or experimenting), I was able to resolve the problem and continue with my project smoothly. Hopefully, this solution can be of help to others facing similar challenges.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Observing data flow in NodeJS where readable stream sends events without any corresponding breaks in communication with the writable stream

Our production environment is experiencing significant memory usage due to high file sizes, stored in S3 and streamed to a local filesystem on EC2 instances. Some clients have files over 6GB, causing the node process to consume large amounts of memory and ...

jQuery Drag Drop Sorting Feature Fails to Work when Moving Items from List to Table Cell

I need assistance with creating a sortable list that can have its items dragged into a table cell, where the items can then be sorted within that cell. The process involves: Dragging a list item into the table cell. Sorting the list item in the secon ...

In the middleware, the request body is empty, but in the controller, it contains content

Below is my server.js file: import express from "express"; import mongoose from "mongoose"; import productRouter from "./routers/productRouter.js"; import dotenv from "dotenv"; dotenv.config(); const app = expres ...

Send error messages directly to the client side or retrieve status codes and messages

When responding to an AJAX request, encountering an app error like data validation failure can be tricky. How can we effectively communicate this to the user? 1. Returning a Status Code and Fetching Message with JS $.ajax(options).done(function(response) ...

Refreshing the page or directly loading it results in a blank screen being displayed

Despite researching various solutions to this common issue, none seem to work for me. Let's dive into it. I've developed a Vue 2 application integrated with Express running on AWS Amplify. When testing the app locally in 'dev' mode (np ...

winston is experiencing difficulty in saving the console message to a file

I am interested in using Winston to log all Console messages, and implementing winston-daily-rotate-file to store and delete logs on a daily basis. When looking at the Console: {"level":"info","message":"Feathers applica ...

The parameter type must be a string, but the argument can be a string, an array of strings, a ParsedQs object, or an array of ParsedQs objects

Still learning when it comes to handling errors. I encountered a (Type 'undefined' is not assignable to type 'string') error in my code Update: I added the entire page of code for better understanding of the issue. type AuthClient = C ...

What is the best way to pass a variable between different modules?

I'm currently working with Node.JS and Express.js, and I am facing a challenge of sharing a variable between different modules. The variable in question is a pool of MySQL connections, which initializes 3 connections at the beginning of Node.js execut ...

Scrolling to the Bottom in AngularJS after Changing Scope or ResourceorHow

So I've been experimenting with using $anchorScroll to achieve a specific effect. However, I'm facing some confusion regarding where exactly to insert the <a id="bottom"> My current view consists of a <table> with a ng-repeat on ...

Trouble with selecting inputs within a Div Element

Could you please review the code below and help me understand why I am unable to retrieve the ID of the selected radio buttons using this.id? <div id="pay" class="btn-group" data-toggle="buttons"> <label class="btn btn-primary"> < ...

What could be causing the ReferenceError when the Response object is not defined?

I am currently working on node.js and express. After attempting to establish a simple server, I am encountering an unexpected response error. const http = require('http'); const myServer = http.createServer(function(req, res){ res.writeHead ...

Conditional jQuery actions based on the selected radio button - utilizing if/else statements

This task seemed simple at first, but I quickly realized it's more challenging than expected. Apologies in advance, as Javascript is not my strong suit. My goal is to have the main button (Get Your New Rate) perform different actions based on whether ...

retrieve the status of a checkbox in a dynamically generated element

I'm currently working on integrating the YouTube API into my app in order to display a dynamic list of cards. The cards are stored in a variable and then added to a playlist container using an each function. Each card contains a toggle switch for use ...

Utilize the effectiveness of the Ajax Success Handler for retrieving a distinct JSON entity

One of the features I am currently using involves an Ajax command that enables me to query data from a local server. In order to ensure smooth execution, it is crucial for me to return a JSON object through the success handler. The specific structure of m ...

The issue with the jQuery class change not being triggered in Internet Explorer seems to be isolated, as Chrome and

This little jQuery script I have is supposed to show a fixed navigation menu once the page has been scrolled below 200px, and then change the class on each menu list item to "current" when that section reaches the top of the viewport. The issue is that th ...

Retrieving information from MySql to display scheduled events on a calendar

Hello, I have integrated Adam Shaw's Full Calendar plugin into my web application. While I am new to using json and understanding its functionality, I am facing difficulty in fetching events from my database and displaying them on the calendar. If any ...

Validation for nested fields in objects using express-validator if the object exists

I am currently working on a Rest API Project using Express and NodeJs, with the addition of Express-Validator for request object validation. Within one of my services, the request body looks like this: { "name": "some value", " ...

JavaScript method for altering the values of variables

Having a small issue with my JavaScript function. Let me tell you what's going on: var intervalId = setInterval(function() { var value = parseInt($('#my_id').text(), 10); if(value > 0) { clearInterval(intervalId); console.log ...

Transforming an object into an interface in TypeScript

Recently, I have started learning Typescript and am currently working on a project where I am building a REST API. In this project, I have defined a specific model for my request payload. However, even after typecasting, the type of 'resObj' rem ...

Creating image links in this jQuery Slider plugin: A beginner's guide

Currently, I am attempting to insert links into each photo within the slider. While I have successfully done this on two other websites, I am encountering difficulties due to variations in the code structure. <a href="http://www.google.com I have expe ...