2013-03-24 6 views
85

Ich bin ein Anfänger zu Angularjs verwenden, und ich versuche, einige Header auf eine Anfrage hinzuzufügen:einen benutzerdefinierten Header zu HTTP-Anforderung Hinzufügen Angularjs

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

ich alle Unterlagen haben gesucht , und das scheint mir, als ob es richtig sein sollte.

Wenn ich eine lokale Datei für die URL in der $http.get verwenden, sehe ich die folgende HTTP-Anforderung auf dem Netzwerk-Registerkarte in 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 

Wie Sie sehen können, beide der Header wurden korrekt hinzugefügt. Aber wenn ich die URL der in der $http.get oben gezeigt ein ändern (außer die reale Adresse, nicht example.com), dann bekomme ich:

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 

Der einzige Unterschied im Code zwischen diesen beiden ist ein für Die erste URL ist eine lokale Datei und für die zweite ist die URL ein Remote-Server. Wenn Sie sich den zweiten Anforderungsheader ansehen, gibt es keinen Authentifizierungsheader, und Accept scheint einen Standard anstelle des angegebenen zu verwenden. Auch die erste Zeile sagt jetzt OPTIONS statt GET (obwohl Access-Control-Request-Method ist GET).

Haben Sie eine Idee, was mit dem obigen Code falsch ist, oder wie Sie die zusätzlichen Header erhalten, wenn Sie keine lokale Datei als Datenquelle verwenden?

+2

Dieses wie ein CORS Problem sieht - nehmen eine längere Hintergrund durch diese Diskussion lesen : https://groups.google.com/forum/#!topic/angular/CSBMY6oXfqs –

+0

Es war in der Tat ein CORS-Problem. Der Server wurde nicht konfiguriert, um den Access-Control-Allow-Origin: -Header zurückzugeben. Wenn Sie eine Antwort mit Ihrem Kommentar und ein bisschen Detail auf CORS schreiben möchten, werde ich Ihre Antwort akzeptieren. Die Antwort unten von Dmitry Evseev und bearbeitet von Ihnen war knapp, aber nicht wirklich das eigentliche Problem. – trentclowater

+1

Chrome überprüft die Anforderung, nach CORS-Headern zu suchen, wenn die Anforderung eine Cross-Domain ist. Überprüfe meine Antwort. –

Antwort

-8

Für mich funktionierte das folgende erläuternde Snippet. Vielleicht sollten Sie nicht ' für Header-Namen verwenden?

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

Ich verwende $http.ajax(), obwohl ich nicht, dass ein Spiel-Wechsler sein erwarten.

60

Ich nahm, was man hatte, und fügte hinzu, eine andere X-Testing Header

var config = {headers: { 
     'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==', 
     'Accept': 'application/json;odata=verbose', 
     "X-Testing" : "testing" 
    } 
}; 

$http.get("/test", config); 

Und im Chrome Registerkarte Netzwerk, ich sehe sie gesendet werden.

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 

Sind Sie sehen sie nicht aus dem Browser oder auf dem Server? Probieren Sie die Browser-Tools oder einen Debug-Proxy aus und sehen Sie, was gesendet wird.

+0

Ich habe keinen Zugriff auf den Server, und im Browser verwende ich Firefox, aber ich sehe die Header, die ich der ursprünglichen Frage oben hinzugefügt habe.Ich sehe nicht, wo Sie die Kopfzeilen auf der Registerkarte "Ressource" in Chrome anzeigen können. – trentclowater

+0

Entschuldigung, ich habe Ihrer Antwort eine Bearbeitung hinzugefügt, die in meiner ursprünglichen Frage enthalten war. – trentclowater

+0

Ich meinte die Netzwerk-Registerkarte der Entwickler-Tools, nicht Ressourcen - Updates Antwort –

2

Was Sie für OPTIONS Anfrage sehen, ist in Ordnung. Autorisierungsheader sind darin nicht enthalten.

Aber damit Basic Auth funktioniert, müssen Sie hinzufügen: withCredentials = true; zu Ihrem var config.

Aus den AngularJS $http documentation:

withCredentials-{boolean} - ob die withCredentials Flagge auf dem XHR Objekt einzustellen. Siehe requests with credentials für weitere Informationen Informationen.

1

Und was ist die Antwort vom Server? Es sollte eine 204 antworten und dann wirklich das GET senden, das Sie anfordern.

In den OPTIONEN prüft der Client, ob der Server CORS-Anfragen zulässt. Wenn es Ihnen etwas anderes als eine 204 gibt, sollten Sie Ihren Server so konfigurieren, dass er die richtigen Allow-Origin-Header sendet.

Die Art, wie Sie Header hinzufügen, ist der richtige Weg.

7

mein Vorschlag wird eine Funktionsaufruf-Einstellungen wie diese innerhalb der Funktion hinzufügen überprüfen Sie die Kopfzeile, die dafür geeignet ist. Ich bin mir sicher, dass es definitiv funktionieren wird. es funktioniert perfekt für mich.

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 || {} 
    }; 
} 

dann Ihre Daten wie nennen dies

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

Wenn Sie Ihre benutzerdefinierte Header auf alle Anforderungen hinzufügen möchten, können Sie die Standardeinstellungen auf $ httpProvider ändern kann immer diesen Header hinzufügen ...

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

ALLE aber OPTIONEN Anforderungen, die – Rocco

+0

ist schönes Beispiel. Kann dies zum Zwischenspeichern von Token zum Umleiten von Seiten verwendet werden? – Martian2049

17

Grundlegende Authentifizierung mit der HTTP POST-Methode:

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

... und GET Methodenaufruf mit Kopf:

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

Chrome ist Preflighting die Anfrage für CORS-Header zu suchen. Wenn die Anfrage akzeptabel ist, wird sie die echte Anfrage senden. Wenn Sie diese domänenübergreifende Domäne verwenden, müssen Sie sich einfach damit befassen oder einen Weg finden, die Anfrage domänenübergreifend zu stellen. Das ist Absicht.

Im Gegensatz zu einfachen Anfragen (oben erörtert), „Preflight“ -Anfragen ersten eine HTTP-Anforderung auf die anderen Domäne auf die Ressource durch die OPTIONS-Methode senden, um festzustellen, ob die tatsächliche Anforderung sicher ist zu senden . Cross-Site-Anfragen werden wie diese Preflight, da sie Auswirkungen auf Benutzerdaten haben können. Insbesondere ist eine Anfrage Preflight wenn:

Es verwendet andere Methoden als GET, HEAD oder POST. Wenn POST zu Anforderungsdaten mit einem anderen Inhaltstyp als -Anwendung/x-www-form-urlencoded, multipart/form-data oder text/plain, z. Wenn die POST-Anfrage eine XML-Payload mit application/xml oder text/xml an den Server sendet, wird die Anfrage mit einem Preflight versehen. Er setzt benutzerdefinierte Header in der Anfrage (zB die Anforderung verwendet einen Header wie X-PINGOTHER)

Ref: AJAX in Chrome sending OPTIONS instead of GET/POST/PUT/DELETE?

Verwandte Themen