如何跳过AngularJS中的OPTIONS预检请求

我开发了一个PhoneGap应用程序,现在正在转换到一个手机网站。 一切工作顺利,除了一个小故障。 我通过POST请求使用某个第三方API,在应用程序中正常工作,但在移动网站版本中失败。

经过仔细观察,看起来像AngularJS(我猜是浏览器)首先发送一个OPTIONS请求。 今天我学到了很多关于CORS的知识,但似乎无法弄清楚如何完全禁用它。 我没有访问该API的权限(所以在这一方的更改是不可能的),但他们已经将我正在工作的域添加到他们的Access-Control-Allow-Origin头。

这是我正在谈论的代码:

var request = { language: 'fr', barcodes: [ { barcode: 'somebarcode', description: 'Description goes here' } ] }; } var config = { headers: { 'Cache-Control': 'no-cache', 'Content-Type': 'application/json' } }; $http.post('http://somedomain.be/trackinginfo', request, config).success(function(data, status) { callback(undefined, data); }).error(function(data, status) { var err = new Error('Error message'); err.status = status; callback(err); }); 

我怎样才能防止浏览器(或AngularJS)发送该OPTIONS请求,只是跳到实际的POST请求? 我正在使用AngularJS 1.2.0。

提前致谢。

印前检查是由您的Content-Type application/json触发的。 最简单的方法是将Content-Type设置为text/plainapplication/x-www-form-urlencodedmultipart/form-data内容types也是可以接受的,但你当然需要适当地格式化你的请求载荷。

如果您在进行此更改后仍然看到预检,那么Angular也可能会为请求添加X标头。

正如Ray所说的,你可以通过修改content-header来阻止它,

  $http.defaults.headers.post["Content-Type"] = "text/plain"; 

例如 –

 angular.module('myApp').factory('User', ['$resource','$http', function($resource,$http){ $http.defaults.headers.post["Content-Type"] = "text/plain"; return $resource(API_ENGINE_URL+'user/:userId', {}, { query: {method:'GET', params:{userId:'users'}, isArray:true}, getLoggedIn:{method:'GET'} }); }]); 

或直接致电 –

 var req = { method: 'POST', url: 'http://example.com', headers: { 'Content-Type': 'text/plain' }, data: { test: 'test' } } $http(req).then(function(){...}, function(){...}); 

这不会发送任何飞行前的选项请求。

注:请求不应该有任何自定义标题参数,如果请求标题包含任何自定义标题,然后浏览器将做飞行前请求,你不能避免它。

我认为最好的办法是检查一下,如果请求的types是“OPTIONS”,则从中间件返回200。 它为我工作。

 express.use('*',(req,res,next) =>{ if (req.method == "OPTIONS") { res.status(200); res.send(); }else{ next(); } }); 

当执行某些types的跨域AJAX请求时,支持CORS的现代浏览器将插入额外的“预检”请求,以确定他们是否有权执行该操作。 从示例查询:

 $http.get( 'https://example.com/api/v1/users/' +userId, {params:{ apiKey:'34d1e55e4b02e56a67b0b66' } } ); 

由于这个片段我们可以看到地址发送了两个请求(OPTIONS和GET)。 来自服务器的响应包括确认查询GET的允许性的标题。 如果您的服务器未configuration为正确处理OPTIONS请求,则客户端请求将失败。 例如:

 Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: accept, origin, x-requested-with, content-type Access-Control-Allow-Methods: DELETE Access-Control-Allow-Methods: OPTIONS Access-Control-Allow-Methods: PUT Access-Control-Allow-Methods: GET Access-Control-Allow-Methods: POST Access-Control-Allow-Orgin: * Access-Control-Max-Age: 172800 Allow: PUT Allow: OPTIONS Allow: POST Allow: DELETE Allow: GET 

将content-type设置为undefined将使javascript传递标头数据,并重写默认的angular度$ httpProvider头部configuration。 Angular $ http文档

 $http({url:url,method:"POST", headers:{'Content-Type':undefined}).then(success,failure);