Angular $ http.delete CORS错误(预检请求)

时间:2015-05-28 04:42:52

标签: jquery angularjs node.js express cors

我有一个Angular应用程序(v1.13.15)和Express.js(v4.12.4)作为后端。

我的后端有一个DELETE方法,我已经为它启用了CORS支持。

但是,当我使用Angular $ http.delete时,我遇到了这个错误

请求的资源上没有“Access-Control-Allow-Origin”标头。

我已经尝试过使用Jquery,$ .ajax()调用它,我也遇到了同样的问题!

我也尝试使用POSTMAN来执行DELETE请求,没有问题。

但是,我使用Angular访问我的GET和POST方法没有问题。

我可以知道这是什么问题吗?

我的后端网址 http://localhost:3000

我使用gulp-webserver为AngularJS提供服务 http://localhost:8000

我的服务器代码

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

和我的角色代码

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

GET和POST方法没问题!只有当我使用DELETE方法时,我遇到了CORS错误!

我在下面附上了使用谷歌浏览器的请求标题的截图

Angular CORs problme

以下是Postman的截图,

POSTMAN delete

4 个答案:

答案 0 :(得分:6)

我设法解决了这个问题,这是由于预检请求

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

在为DELETE执行CORS时,它首先会向服务器发送一个OPTIONS方法,然后它将解析为DELETE方法

所以它在后端,我应该有OPTIONS的路由,然后调用next()将它传递给DELETE方法

后端代码:

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

和我的路由器中间件

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能够执行DELETE请求吗? (这是因为它向我的服务器发送DELETE http请求,而不是OPTIONS),而在Web浏览器中,它会发送一个OPTIONS用于预检请求(这主要是为了安全问题)

* shoutout to @FrankerZ,他让我想要比较POSTMAN和我的Chrome结果,然后我发现访问控制允许方法有所不同,这导致我尝试使用cors中间件(https://www.npmjs.com/package/cors),并且它工作,然后我设法解决问题,并由于预检请求!

答案 1 :(得分:0)

您可以使用cors npm模块启用交叉域请求

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

答案 2 :(得分:0)

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

您可以定义自己的选项回调(不必相同)。

答案 3 :(得分:0)

预检请求仅发送标头而不是标头值。因此,这会引起问题。

需要从客户端和服务器端处理CORS。

我在server.js文件中添加了以下标题设置(应用程序在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();
});

从服务器端我们也必须处理CORS请求。

以下是服务器端API(应用程序在java jersey框架中)中所做的更改

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

此预检问题仅在我们尝试从不同来源连接到localhost时发生。