使用angular.js将自定义头添加到HTTP请求

我是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的networking标签上看到以下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是远程服务器。 如果您查看第二个请求标头,则不存在Authentication标头,并且Accept似乎使用默认值而不是指定的标头。 另外,第一行现在说OPTIONS而不是GET (尽pipeAccess-Control-Request-MethodGET )。

任何想法上面的代码有什么问题,或者如何获取附加头包括使用时不使用本地文件作为数据源?

我拿了你的东西,并添加了另一个X-Testing标题

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

在Chromenetworking标签中,我看到他们正在发送。

 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 

你没有看到他们从浏览器,或在服务器上? 尝试浏览器工具或debugging代理,看看发送了什么。

使用HTTP POST方法的基本authentication:

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

我的build议是在function里面添加一个像这样的函数调用设置,检查适合它的头。 我相信这肯定会奏效。 它完全为我工作。

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

如果你想添加你的自定义标题到所有请求,你可以改变$ httpProvider的默认值来始终添加这个标题…

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

你看到的选项请求罚款。 授权标头不公开在其中。

但为了使基本身份validation正常工作,您需要添加: withCredentials = true; 到你的var config

从AngularJS $ http文档 :

withCredentials{boolean} – 是否在XHR对象上设置withCredentials标志。 查看具有凭据的请求以获取更多信息

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

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

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

Chrome正在预查找CORS标题的请求。 如果请求可以接受,则会发送真正的请求。 如果你正在做这个跨域,你只需要处理它,或者find一种方法来使请求非跨域。 这是devise。

与上面讨论的简单请求不同,“预检”请求首先通过OPTIONS方法向另一个域上的资源发送HTTP请求,以确定实际请求是否安全发送。 跨站点请求是这样预检的,因为它们可能会影响用户数据。 特别是,如果出现以下情况,则会请求一个请求:

它使用GET,HEAD或POST以外的方法。 另外,如果使用POST来发送具有除application / x-www-form-urlencoded,multipart / form-data或text / plain之外的Content-Type的请求数据,例如,如果POST请求将XML有效载荷发送到服务器使用application / xml或text / xml,那么请求是预冲的。 它在请求中设置自定义标题(例如,请求使用X-PINGOTHER等标题)

参考: Chrome浏览器中的AJAX发送OPTIONS而不是GET / POST / PUT / DELETE?

对于我来说,下面的解释片段工作。 也许你不应该使用'标题名称?

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

我使用$http.ajax() ,但我不希望这是一个游戏改变者。