我是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
中使用本地文件作为网址时,我在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是远程服务器。如果查看第二个Request标头,则没有Authentication标头,Accept
似乎使用的是默认值而不是指定的默认值。此外,第一行现在显示OPTIONS
而不是GET
(尽管Access-Control-Request-Method
是GET
)。
知道上面的代码有什么问题,或者在不使用本地文件作为数据源时如何使用其他标题?
答案 0 :(得分:65)
我拿走了你的内容,并添加了另一个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
您是否从浏览器或服务器上看到它们?尝试浏览器工具或调试代理,看看发送的是什么。
答案 1 :(得分:21)
使用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
}
});
答案 2 :(得分:8)
如果要将自定义标头添加到所有请求,可以更改$ httpProvider上的默认值以始终添加此标头...
app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common = {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json;odata=verbose'
};
}]);
答案 3 :(得分:7)
我的建议是添加这样的函数调用设置 在函数内部检查适合它的标题。我相信它肯定会奏效。它非常适合我。
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);
答案 4 :(得分:2)
您对OPTIONS请求的看法很好。授权标头不会公开在其中。
但为了让基本身份验证工作,您需要将withCredentials = true;
添加到var config
。
来自AngularJS $http documentation:
withCredentials -
{boolean}
- 是否设置withCredentials
XHR对象上的标志。有关详情,请参阅requests with credentials 信息。
答案 5 :(得分:1)
服务器的答案是什么?它应该回复204,然后真正发送你要求的GET。
在OPTIONS中,客户端正在检查服务器是否允许CORS请求。如果它给你的东西不同于204,那么你应该配置你的服务器发送正确的Allow-Origin标题。
添加标题的方式是正确的方法。
答案 6 :(得分:1)
Chrome正在预检查找CORS标头的请求。如果请求是可接受的,它将发送实际请求。如果您正在执行此跨域,则只需处理它,或者找到一种方法来使请求成为非跨域。这是设计的。
与简单请求(如上所述)不同,"预先发布"首先要求 通过OPTIONS方法向该资源发送HTTP请求 其他域,以确定实际请求是否安全 发送。跨站请求是这样的预检,因为它们可能 对用户数据有影响。特别是,请求是 预防如果:
它使用GET,HEAD或POST以外的方法。此外,如果使用POST 使用除以外的Content-Type发送请求数据 application / x-www-form-urlencoded,multipart / form-data或text / plain, 例如如果POST请求使用XML向服务器发送XML有效负载 application / xml或text / xml,然后请求被预检。它设定 请求中的自定义标头(例如,请求使用标头,例如 X-PINGOTHER)
参考:AJAX in Chrome sending OPTIONS instead of GET/POST/PUT/DELETE?
答案 7 :(得分:0)
您只是添加了服务器不允许的标头。
例如 - 您的服务器设置了 CORS 以仅允许这些标头(接受、缓存控制、编译指示、内容类型、来源)
并在您的 http 请求中添加这样的内容
headers: {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json',
'x-testing': 'testingValue'
}
那么服务器会拒绝这个请求,因为(授权和x-testing)是不允许的。
这是服务器端配置。
并且与 HTTP 选项无关,它只是对来自不同域的服务器的预检,以检查服务器是否允许实际调用。
答案 8 :(得分:-8)
对我来说,下面的解释性片段有效。也许您不应该使用'
作为标题名称?
{
headers: {
Authorization: "Basic " + getAuthDigest(),
Accept: "text/plain"
}
}
我正在使用$http.ajax()
,但我不希望这会改变游戏规则。