使用angular.js为HTTP请求添加自定义报头

Adding a custom header to HTTP request using angular.js

本文关键字:添加 自定义 报头 请求 HTTP angular js 使用      更新时间:2023-09-26

我是angular.js的新手,我试图在请求中添加一些标头:

   var config = {headers: {
            'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
            'Accept': 'application/json;odata=verbose'
        }
    };
   $http.get('https://www.example.com/ApplicationData.svc/Malls(1)/Retailers', config).success(successCallback).error(errorCallback);

我看了所有的文档,在我看来这应该是正确的。

当我在$http.get中使用本地文件的URL时,我在Chrome的网络选项卡上看到以下HTTP请求:

GET /app/data/offers.json HTTP/1.1
Host: www.example.com
Connection: keep-alive
Cache-Control: max-age=0
If-None-Match: "0f0abc9026855b5938797878a03e6889"
Authorization: Basic Y2hhZHN0b25lbWFuOkNoYW5nZV9tZQ==
Accept: application/json;odata=verbose
X-Requested-With: XMLHttpRequest
If-Modified-Since: Sun, 24 Mar 2013 15:58:55 GMT
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
X-Testing: Testing
Referer: http://www.example.com/app/index.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

可以看到,两个头文件都被正确添加了。但是,当我将URL更改为上面$http.get中显示的URL时(除了使用真实地址,而不是example.com),然后我得到:

OPTIONS /ApplicationData.svc/Malls(1) HTTP/1.1
Host: www.datahost.net
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://mpon.site44.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
Access-Control-Request-Headers: accept, origin, x-requested-with, authorization, x-testing
Accept: */*
Referer: http://mpon.site44.com/app/index.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

这两个代码之间的唯一区别是,第一个URL是本地文件,第二个URL是远程服务器。如果您查看第二个请求头,没有身份验证头,并且Accept似乎使用默认值而不是指定的。另外,第一行现在是OPTIONS而不是GET(尽管Access-Control-Request-MethodGET)。

任何想法是什么是错误的上面的代码,或者如何获得额外的头包括使用时不使用本地文件作为数据源?

我把你的,并添加另一个X-Testing

var config = {headers:  {
        'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
        'Accept': 'application/json;odata=verbose',
        "X-Testing" : "testing"
    }
};
$http.get("/test", config);

在Chrome网络选项卡中,我看到它们正在发送。

GET /test HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Accept: application/json;odata=verbose
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
Authorization: Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==
X-Testing: testing
Referer: http://localhost:3000/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

您没有从浏览器或服务器上看到它们吗?请尝试浏览器工具或调试代理,查看正在发送的内容。

使用HTTP POST方法的基本身份验证:

$http({
    method: 'POST',
    url: '/API/authenticate',
    data: 'username=' + username + '&password=' + password + '&email=' + email,
    headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        "X-Login-Ajax-call": 'true'
    }
}).then(function(response) {
    if (response.data == 'ok') {
        // success
    } else {
        // failed
    }
});

…和GET方法调用头:

$http({
    method: 'GET',
    url: '/books',
    headers: {
        'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
        'Accept': 'application/json',
        "X-Login-Ajax-call": 'true'
    }
}).then(function(response) {
    if (response.data == 'ok') {
        // success
    } else {
        // failed
    }
});

如果你想添加自定义头到所有请求,你可以改变$httpProvider的默认值,总是添加这个头…

app.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.defaults.headers.common = { 
        'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
        'Accept': 'application/json;odata=verbose'
      };
}]);

我的建议是像这样添加一个函数调用设置在函数内部检查适合它的头文件。我相信它一定会成功的。这对我来说非常有效。

function getSettings(requestData) {
    return {
        url: requestData.url,
        dataType: requestData.dataType || "json",
        data: requestData.data || {},
        headers: requestData.headers || {
            "accept": "application/json; charset=utf-8",
            'Authorization': 'Bearer ' + requestData.token
        },
        async: requestData.async || "false",
        cache: requestData.cache || "false",
        success: requestData.success || {},
        error: requestData.error || {},
        complete: requestData.complete || {},
        fail: requestData.fail || {}
    };
}

然后像这样调用你的数据

    var requestData = {
        url: 'API end point',
        data: Your Request Data,
        token: Your Token
    };
    var settings = getSettings(requestData);
    settings.method = "POST"; //("Your request type")
    return $http(settings);

您看到的OPTIONS请求很好。授权头在其中不公开。

但是为了基本的授权工作,你需要添加:withCredentials = true;到你的var config

来自AngularJS的$http文档:

withCredentials - {boolean} -是否设置withCredentials标记在XHR对象上。有关更多信息,请参阅带凭据的请求信息。

服务器的答案是什么?它应该回复一个204,然后真正发送您请求的GET。

在OPTIONS中客户端正在检查服务器是否允许CORS请求。如果它给你的不是204,那么你应该配置你的服务器发送正确的Allow-Origin报头。

你添加标题的方式是正确的。

Chrome正在预飞行查找CORS标头的请求。如果请求是可接受的,那么它将发送真正的请求。如果您跨域执行此操作,则只需处理它,或者找到一种使请求非跨域的方法。这是故意的。

与前面讨论的简单请求不同,"预飞行"请求首先出现通过OPTIONS方法向资源发送HTTP请求其他域,以确定实际请求是否安全发送。跨站点请求是这样预先发送的,因为它们可能对用户数据有影响。特别地,请求是起飞前的如果:

它使用GET、HEAD或POST以外的方法。同样,如果POST用于使用Content-Type以外的类型发送请求数据Application/x-www-form-urlencoded, multipart/form-data,或text/plain例如,如果POST请求向服务器发送XML有效负载,使用Application/xml或text/xml,那么请求就被预先处理了。它集请求中的自定义报头(例如,请求使用诸如X-PINGOTHER)

Ref: AJAX在Chrome发送选项而不是GET/POST/PUT/DELETE?

您只是在添加服务器不允许的标头。

例如-你的服务器设置CORS只允许这些头(accept,cache-control,pragma,content-type,origin)

在你的HTTP请求中你添加了这样的

 headers: {
        'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
        'Accept': 'application/json',
        'x-testing': 'testingValue'
    }

则服务器将拒绝此请求,因为(授权和x-测试)是不允许的。

服务器端配置

与HTTP选项无关,它只是一个从不同域到服务器的预飞行,以检查服务器是否允许实际调用

对我来说,下面的解释性代码片段是有效的。也许你不应该使用'作为标题名?

{
   headers: { 
      Authorization: "Basic " + getAuthDigest(), 
      Accept: "text/plain" 
   }
}

我使用的是$http.ajax(),虽然我不期望它会改变游戏规则。