angularjs 如何跳过OPTIONS飞行前请求?

oo7oh9g9  于 2022-12-22  发布在  Angular
关注(0)|答案(6)|浏览(258)

我开发了一个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。

gjmwrych

gjmwrych1#

印前检查是由您的内容类型application/json触发的。防止这种情况发生的最简单的方法是将内容类型设置为text/plainapplication/x-www-form-urlencodedmultipart/form-data内容类型也是可以接受的,但您当然需要适当地格式化您的请求负载。
如果您在进行此更改后仍看到印前检查,则Angular可能也会向请求中添加X标题。
或者,您可能具有将触发它的标头(授权、缓存控制...),请参见:

  • https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS#Preflighted_requests
5jvtdoz2

5jvtdoz22#

就像雷说的,你可以通过修改内容头来阻止它-

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

这不会发送任何预检选项请求。

**注意:**请求不应有任何自定义标题参数,如果请求标题包含任何自定义标题,则浏览器将进行预检请求,您无法避免。

edqdpe6u

edqdpe6u3#

当执行某些类型的跨域 AJAX 请求时,支持CORS的现代浏览器将插入额外的“预检”请求,以确定它们是否具有执行该操作的权限。

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

由于这个片段,我们可以看到向该地址发送了两个请求(OPTIONS和GET)。来自服务器的响应包括确认查询GET的允许性的标头。如果您的服务器未配置为正确处理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
gudnpqoy

gudnpqoy4#

我认为最好的方法是检查请求类型是否为“选项”,从中间件返回200。

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

pkwftd7m5#

印前检查是浏览器实现的一项网络安全功能。对于Chrome,您可以通过添加--disable-web-security标志来禁用所有网络安全。
例如:"C:\Program Files\Google\Chrome\Application\chrome.exe"--disable-web-security--user-data-dir ="C:\newChromeSettingsWithoutSecurity"。您可以先创建一个新的镶边快捷方式,然后转到其属性并按照上面的方法更改目标。这应该会有帮助!

xzv2uavs

xzv2uavs6#

将content-type设置为undefined将使javascript按原样传递头数据,并覆盖默认的Angular $httpProvider头配置。Angular $http Documentation

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

相关问题