Javascript 使用angular.js向HTTP请求添加自定义头

Javascript 使用angular.js向HTTP请求添加自定义头,javascript,angularjs,http-headers,Javascript,Angularjs,Http Headers,我是angular.js的新手,我正在尝试向请求添加一些标题: var config = {headers: { 'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==', 'Accept': 'application/json;odata=verbose' } }; $http.get('https://www.example.com/Applicat

我是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
似乎使用了默认值,而不是指定的值。此外,第一行现在显示的是
选项
,而不是
获取
(尽管
访问控制请求方法
获取


你知道上面的代码有什么问题吗,或者在不使用本地文件作为数据源时,如何获取包含的附加头?

对我来说,下面的解释性片段很有效。也许您不应该使用
作为标题名

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

我使用的是
$http.ajax()
,但我不认为这会改变游戏规则。

我拿走了你的东西,并添加了另一个
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

您是不是从浏览器或服务器上看不到它们?尝试使用浏览器工具或调试代理,查看发送的内容。

您在选项请求中看到的内容没有问题。授权标题未在其中公开

但是为了使基本身份验证工作,您需要添加:
withCredentials=true到您的
var配置

来自AngularJS:

withCredentials-
{boolean}
-是否设置
withCredentials
XHR对象上的标志。查看更多信息 信息


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

在选项中,客户端检查服务器是否允许CORS请求。如果它提供了与204不同的内容,则应配置服务器以发送正确的Allow Origin标头


添加标题的方法是正确的。

我的建议是添加这样的函数调用设置 在函数内部,检查适合它的标题。我相信它一定会奏效。这对我来说非常有效

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);
 headers: {
        'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
        'Accept': 'application/json',
        'x-testing': 'testingValue'
    }

如果要将自定义标头添加到所有请求,可以将$httpProvider上的默认值更改为始终添加此标头

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

使用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
    }
});
…并使用标头获取方法调用:

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

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

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

它使用的方法不是GET、HEAD或POST。另外,如果POST用于 发送内容类型不是的请求数据 application/x-www-form-urlencoded、多部分/表单数据或text/plain, e、 g.如果POST请求使用 application/xml或text/xml,则请求被预引导。它设定 请求中的自定义标头(例如,请求使用诸如 X射线(其他)


Ref:

您只是添加了一个服务器不允许的头

例如,您的服务器设置为CORS只允许这些头(接受、缓存控制、pragma、内容类型、来源)

在您的http请求中,您要添加如下内容

    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);
 headers: {
        'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
        'Accept': 'application/json',
        'x-testing': 'testingValue'
    }
然后服务器将拒绝此请求,因为(授权和x测试)是不允许的

这是服务器端配置


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

我没有访问服务器的权限,在浏览器上我使用Firefox,但我看到了我添加到上面原始问题的标题。我看不到你可以在Chrome中的“资源”选项卡上查看标题的位置。对不起,我在你的回答中添加了一个编辑,这是我的原始问题。我指的是“开发人员工具”的“网络”选项卡,而不是“资源-更新”回答。我在问题中添加了更多信息。看起来标题是在一种情况下添加的,但不是在另一种情况下添加的。这看起来像是一个CORS问题——请通读本讨论,了解一些背景:它确实是一个CORS问题。服务器未配置为返回Access Control Allow Origin:标头。如果你想写一个关于CORS的评论和一点细节的答案,我会接受你的答案。下面由Dmitry Evseev提供并由您编辑的答案很接近,但不是真正的问题。如果请求是跨域的,Chrome正在预处理请求以查找CORS头。检查我的答案。除了选项外,所有的请求都是很好的例子。这可以用来缓存重定向页面的令牌吗?这是最好的答案。