Aggiunta di un’intestazione personalizzata alla richiesta HTTP utilizzando angular.js

Sono un novizio di angular.js e sto cercando di aggiungere alcune intestazioni a una richiesta:

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

Ho esaminato tutta la documentazione e mi sembra che dovrebbe essere corretta.

Quando utilizzo un file locale per l’URL in $http.get , vedo la seguente richiesta HTTP nella scheda di rete 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 

Come puoi vedere, entrambe le intestazioni sono state aggiunte correttamente. Ma quando cambio l’URL a quello mostrato nel $http.get sopra (tranne usando l’indirizzo reale, non example.com), allora ottengo:

 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 

L’unica differenza di codice tra questi due è che uno è per il primo che l’URL è un file locale e per il secondo l’URL è un server remoto. Se si guarda la seconda intestazione della richiesta, non vi è alcuna intestazione di autenticazione e sembra che Accept utilizzi un valore predefinito al posto di quello specificato. Inoltre, la prima riga ora dice OPTIONS invece di GET (sebbene GET sia Access-Control-Request-Method ).

Qualche idea di cosa non funziona nel codice precedente o di come includere le intestazioni aggiuntive quando non si utilizza un file locale come origine dati?

Ho preso quello che avevi e ho aggiunto un’altra intestazione X-Testing

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

E nella scheda della rete di Chrome, li vedo inviati.

 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 

Non li vedi dal browser o sul server? Prova gli strumenti del browser o un proxy di debug e vedi cosa viene inviato.

Autenticazione di base con metodo 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 } }); 

… e chiama il metodo GET con l’intestazione:

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

il mio suggerimento sarà aggiungere una funzione chiamata impostazioni come questa all’interno della funzione controllare l’intestazione che è appropriata per esso. Sono sicuro che funzionerà sicuramente. funziona perfettamente per me

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

quindi chiama i tuoi dati in questo modo

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

Se vuoi aggiungere le tue intestazioni personalizzate a TUTTE le richieste, puoi modificare le impostazioni predefinite su $ httpProvider per aggiungere sempre questa intestazione …

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

Quello che vedi per la richiesta OPTIONS va bene. Le intestazioni di authorization non sono esposte al suo interno.

Ma per far funzionare l’autenticazione di base è necessario aggiungere: withCredentials = true; alla tua var config .

Dalla documentazione http AngularJS $ :

withCredentials{boolean} – se impostare il flag withCredentials sull’object XHR. Vedi le richieste con credenziali per ulteriori informazioni.

E qual è la risposta dal server? Dovrebbe rispondere a 204 e quindi inviare veramente il GET che stai richiedendo.

Nelle OPZIONI il client sta verificando se il server consente le richieste CORS. Se ti dà qualcosa di diverso da un 204 allora dovresti configurare il tuo server per inviare le intestazioni Allow-Origin corrette.

Il modo in cui aggiungi intestazioni è il modo giusto per farlo.

Chrome esegue il preflight della richiesta per cercare le intestazioni CORS. Se la richiesta è accettabile, invierà la richiesta reale. Se stai facendo questo cross-domain, dovrai semplicemente gestirlo o trovare un modo per rendere la richiesta non-cross-domain. Questo è di design.

A differenza delle richieste semplici (discusse sopra), le richieste “preflighted” prima inviano una richiesta HTTP dal metodo OPTIONS alla risorsa sull’altro dominio, al fine di determinare se la richiesta effettiva è sicura da inviare. Le richieste cross-site sono preflight in questo modo poiché potrebbero avere implicazioni per i dati dell’utente. In particolare, una richiesta è preflight se:

Utilizza metodi diversi da GET, HEAD o POST. Inoltre, se POST viene utilizzato per inviare dati di richiesta con un Content-Type diverso da application / x-www-form-urlencoded, multipart / form-data o text / plain, ad esempio se la richiesta POST invia un payload XML al server usando application / xml o text / xml, quindi la richiesta è preflight. Imposta le intestazioni personalizzate nella richiesta (ad esempio la richiesta utilizza un’intestazione come X-PINGOTHER)

Rif: AJAX in Chrome invia OPZIONI invece di GET / POST / PUT / DELETE?

Per me il seguente frammento esplicativo ha funzionato. Forse non dovresti usare ' per il nome dell’intestazione?

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

Sto usando $http.ajax() , anche se non mi aspetterei che sia un punto di svolta.