web-dev-qa-db-ja.com

angular.jsを使ってHTTPリクエストにカスタムヘッダを追加する

私は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のURLにローカルファイルを使用すると、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

これら2つのコードの唯一の違いは、1つ目はURLがローカルファイルで、2つ目がURLがリモートサーバーであることです。 2番目のRequestヘッダーを見ると、Authenticationヘッダーはなく、Acceptは指定されたものではなくデフォルトを使用しているように見えます。また、最初の行にOPTIONSではなくGETと表示されるようになりました(ただしAccess-Control-Request-MethodGETです)。

上記のコードの何が問題になっているのか、またはローカルファイルをデータソースとして使用していないときに追加のヘッダーを含めるにはどうすればよいですか。

89
trentclowater

私はあなたが持っているものを取り、そして別の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

あなたはそれらをブラウザから見ていませんか、それともサーバ上で見ませんか?ブラウザのツールまたはデバッグプロキシを試して、何が送信されているのかを確認してください。

65
Kevin Hakanson

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

カスタムヘッダをすべてのリクエストに追加したい場合は、$ httpProviderのデフォルトを変更して常にこのヘッダを追加することができます。

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

私の提案はそれのために適切であるヘッダーをチェックする機能の中のこのような機能呼び出し設定を追加することです。きっとうまくいくと確信しています。それは私にとっては完璧に機能しています。

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

OPTIONSリクエストに対して表示されるものは問題ありません。認証ヘッダーは公開されていません。

しかし基本認証が機能するためには、あなたのwithCredentials = true;var configを追加する必要があります。

AngularJSから $ http documentation

withCredentials - {boolean} - XHRオブジェクトにwithCredentialsフラグを設定するかどうか。詳しくは 信任状のある要求 を参照してください。

2
Dmitry Evseev

Chromeは、CORSヘッダを探すという要求を強調しています。要求が受け入れられる場合は、実際の要求を送信します。このクロスドメインを使用している場合は、単にそれに対処するか、そうでなければ要求を非クロスドメインにする方法を見つける必要があります。これは仕様によるものです。

単純なリクエスト(前述)とは異なり、実際にリクエストを送信しても安全かどうかを判断するために、「プリフライト」リクエストは最初にOPTIONSメソッドによって他のドメインのリソースにHTTPリクエストを送信します。クロスサイトリクエストはユーザーデータに影響を与える可能性があるため、このようにプリフライトされます。特に、次の場合にリクエストがプリフライトされます。

GET、HEAD、POST以外のメソッドを使用します。また、POSTがapplication/x-www-form-urlencoded、multipart/form-data、またはtext/plain以外のContent-Typeで要求データを送信するために使用される場合。 POSTリクエストがapplication/xmlまたはtext/xmlを使用してXMLペイロードをサーバーに送信する場合、リクエストはプリフライトされます。それはリクエストにカスタムヘッダを設定します(例えばリクエストはX-PINGOTHERのようなヘッダを使用します)

Ref: ChromeのAJAXはGET/POST/PUT/DELETEの代わりにOPTIONSを送信しますか?

1
Asim K T

そして、サーバーからの答えは何ですか? 204を返信してから、実際に要求しているGETを送信する必要があります。

OPTIONSでは、クライアントはサーバーがCORS要求を許可しているかどうかをチェックしています。それが204と違う何かをあなたに与えるなら、あなたは正しいAllow-Originヘッダを送るようにあなたのサーバを設定するべきです。

あなたがヘッダーを追加している方法はそれを行うための正しい方法です。

1
ghostbar