Angular $ http.delete 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方法没有问题。
我可以知道这是什么问题吗?
我的后端URL http:// localhost:3000
我使用gulp-webserver http:// localhost:8000为我的AngularJS提供服务
我的服务器代码
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错误!
我已使用谷歌浏览器在下面附上了截图请求标题
以下是Postman的截图,
我设法解决了这个问题,这是由于预检请求
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用于预检请求(这主要是出于安全考虑)
*请关注@FrankerZ,他让我比较POSTMAN和我的Chrome结果,然后我看到访问控制允许方法有所不同,这导致我尝试使用cors中间件( https://www.npmjs.com/package / cors ),它工作,然后我设法解决问题,并由于预检请求!
您可以使用cors npm模块启用交叉域请求
app.options('/gps/:id', function(req, res) { res.json({}) }); app.delete('/gps/:id', routes.gps.optionGPSData);
你可以定义自己的选项回调(不必相同)。
预检请求仅发送标头而不是标头值。 因此,这会引起问题。
需要从客户端和服务器端处理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时,才会发生此预检问题。