web-dev-qa-db-fra.com

Ajout d'un en-tête personnalisé à la requête HTTP à l'aide de angular.js

Je suis novice sur angular.js et j'essaie d'ajouter quelques en-têtes à une requête:

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

J'ai examiné toute la documentation et il me semble que cela devrait être correct.

Lorsque j'utilise un fichier local pour l'URL dans le $http.get, la requête HTTP suivante apparaît sur l'onglet Réseau de 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

Comme vous pouvez le constater, les deux en-têtes ont été ajoutés correctement. Mais lorsque je remplace l'URL par celle indiquée dans le $http.get ci-dessus (à l'exception de l'adresse réelle et non de example.com), je reçois:

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

La seule différence de code entre ces deux types est que l'un correspond au premier: l'URL est un fichier local et, pour le second, à un serveur distant. Si vous examinez le deuxième en-tête Request, il n'y a pas d'en-tête d'authentification et le Accept semble utiliser une valeur par défaut au lieu de celle spécifiée. En outre, la première ligne indique maintenant OPTIONS au lieu de GET (bien que Access-Control-Request-Method soit GET).

Avez-vous une idée de ce qui ne va pas avec le code ci-dessus ou comment obtenir les en-têtes supplémentaires inclus lorsque vous n’utilisez pas un fichier local en tant que source de données?

89
trentclowater

J'ai pris ce que vous aviez et ajouté un autre en-tête X-Testing

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

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

Et dans l'onglet de réseau Chrome, je les vois être envoyés.

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

Ne les voyez-vous pas depuis le navigateur ou sur le serveur? Essayez l’outillage du navigateur ou un proxy de débogage et voyez ce qui est envoyé.

65
Kevin Hakanson

Authentification de base à l'aide de la méthode 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
    }
});

... et appel de méthode GET avec en-tête:

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

Si vous souhaitez ajouter vos en-têtes personnalisés à TOUTES les demandes, vous pouvez modifier les valeurs par défaut de $ httpProvider afin de toujours ajouter cet en-tête…

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

ma suggestion sera d'ajouter un paramètre d'appel de fonction comme celui-ci à l'intérieur de la fonction, cochez l'en-tête approprié. Je suis sûr que ça va définitivement marcher. cela fonctionne parfaitement pour moi.

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

alors appelez vos données comme ça

    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
Riyadh Ul Islam

Ce que vous voyez pour la demande OPTIONS va bien. Les en-têtes d'autorisation n'y sont pas exposés.

Mais pour que l'authentification de base fonctionne, vous devez ajouter: withCredentials = true; à votre var config.

Depuis AngularJS documentation $ http :

withCredentials - {boolean} - indique s'il faut définir l'indicateur withCredentials sur l'objet XHR. Voir demandes avec identifiants pour plus d'informations.

2
Dmitry Evseev

Chrome contrôle en amont la demande de recherche des en-têtes CORS. Si la demande est acceptable, il enverra alors la demande réelle. Si vous faites ce domaine, vous devrez simplement vous en occuper ou bien trouver un moyen de rendre la demande non-domaine. C'est par conception.

Contrairement aux requêtes simples (décrites ci-dessus), les requêtes "pré-contrôlées" envoient d'abord une requête HTTP par la méthode OPTIONS à la ressource de l'autre domaine, afin de déterminer si la requête réelle peut être envoyée en toute sécurité. Les requêtes intersites font l’objet d’un contrôle en amont de la sorte car elles peuvent avoir des conséquences sur les données de l’utilisateur. En particulier, une demande est contrôlée en amont si:

Il utilise des méthodes autres que GET, HEAD ou POST. De même, si POST est utilisé pour envoyer des données de demande avec un type de contenu autre que application/x-www-form-urlencoded, multipart/form-data ou text/plain, par exemple. si la demande POST envoie une charge XML au serveur à l'aide de application/xml ou text/xml, la demande est soumise à un contrôle en amont. Il définit des en-têtes personnalisés dans la demande (par exemple, la demande utilise un en-tête tel que X-PINGOTHER).

Réf.: AJAX dans Chrome envoi d’OPTIONS au lieu de GET/POST/PUT/DELETE?

1
Asim K T

Et quelle est la réponse du serveur? Il devrait répondre par 204 et ensuite envoyer réellement le GET que vous demandez.

Dans les OPTIONS, le client vérifie si le serveur autorise les demandes CORS. Si cela vous donne un résultat différent de 204, vous devez configurer votre serveur pour envoyer les en-têtes Allow-Origin appropriés.

La façon dont vous ajoutez des en-têtes est la bonne façon de le faire.

1
ghostbar