Jestem nowicjuszem w angular.js i próbuję dodać kilka nagłówków do żądania:
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);
Przejrzałem całą dokumentację i wydaje mi się, że powinna być poprawna.
Kiedy używam lokalnego pliku jako adresu URL w $http.get
, widzę następujące żądanie HTTP na karcie sieci w Chrome:
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
Jak widać, oba nagłówki zostały poprawnie dodane. Ale kiedy zmieniam adres URL na pokazany $http.get
powyżej (z wyjątkiem użycia prawdziwego adresu, a nie example.com), otrzymuję:
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
Jedyna różnica w kodzie między tymi dwoma jest taka, że po pierwsze adres URL jest plikiem lokalnym, a po drugie adres URL jest serwerem zdalnym. Jeśli spojrzysz na drugi nagłówek żądania, nie ma nagłówka Authentication i Accept
wygląda na to, że używa domyślnego zamiast określonego. Ponadto pierwsza linia mówi teraz OPTIONS
zamiast GET
(chociaż Access-Control-Request-Method
jest GET
).
Masz jakiś pomysł, co jest nie tak z powyższym kodem lub jak uzyskać dodatkowe nagłówki dołączone, gdy nie używasz pliku lokalnego jako źródła danych?
źródło
Odpowiedzi:
Wziąłem to, co miałeś i dodałem kolejny
X-Testing
nagłówekvar config = {headers: { 'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==', 'Accept': 'application/json;odata=verbose', "X-Testing" : "testing" } }; $http.get("/test", config);
A na karcie sieci Chrome widzę, że są wysyłane.
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
Nie widzisz ich w przeglądarce lub na serwerze? Wypróbuj narzędzia przeglądarki lub serwer proxy do debugowania i zobacz, co jest wysyłane.
źródło
Uwierzytelnianie podstawowe metodą 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 } });
... i wywołanie metody GET z nagłówkiem:
$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 } });
źródło
Jeśli chcesz dodać własne nagłówki do WSZYSTKICH żądań, możesz zmienić ustawienia domyślne w $ httpProvider, aby zawsze dodawać ten nagłówek…
app.config(['$httpProvider', function ($httpProvider) { $httpProvider.defaults.headers.common = { 'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==', 'Accept': 'application/json;odata=verbose' }; }]);
źródło
moją sugestią będzie dodanie ustawień wywołania funkcji, takich jak to, wewnątrz funkcji sprawdź nagłówek, który jest dla niej odpowiedni. Jestem pewien, że to na pewno zadziała. to dla mnie doskonale działa.
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 || {} }; }
następnie zadzwoń do swoich danych w ten sposób
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);
źródło
To, co widzisz dla żądania OPCJI, jest w porządku. Nagłówki autoryzacji nie są w nim ujawniane.
Ale aby podstawowa autoryzacja działała, musisz dodać:
withCredentials = true;
do swojegovar config
.Z dokumentacji AngularJS $ http :
źródło
A jaka jest odpowiedź z serwera? Powinien odpowiedzieć na 204, a następnie naprawdę wysłać żądanie GET.
W OPCJACH klient sprawdza, czy serwer zezwala na żądania CORS. Jeśli daje coś innego niż 204, powinieneś skonfigurować serwer, aby wysyłał prawidłowe nagłówki Allow-Origin.
Sposób, w jaki dodajesz nagłówki, to właściwy sposób.
źródło
Chrome wstępnie sprawdza żądanie wyszukania nagłówków CORS. Jeśli żądanie zostanie zaakceptowane, wyśle prawdziwe żądanie. Jeśli robisz to w wielu domenach, będziesz musiał po prostu sobie z tym poradzić lub znaleźć sposób, aby żądanie nie było międzydomenowe. Jest to zgodne z projektem.
Ref: AJAX w Chrome wysyła OPCJE zamiast GET / POST / PUT / DELETE?
źródło
Dla mnie zadziałał następujący fragment wyjaśniający. Być może nie powinieneś używać
'
nazwy nagłówka?{ headers: { Authorization: "Basic " + getAuthDigest(), Accept: "text/plain" } }
Używam
$http.ajax()
, chociaż nie spodziewałbym się, że to zmieni grę.źródło