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


89

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

私はすべてのドキュメントを見てきましたが、これは正しいはずです。

のURLにローカルファイルを使用すると$http.get、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上記のように変更すると(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つのコードの唯一の違いは、最初のURLがローカルファイルであり、2番目のURLがリモートサーバーであることです。2番目のリクエストヘッダーを見ると、認証ヘッダーはAcceptなく、は指定されたものではなくデフォルトを使用しているようです。また、最初の行は、今言うOPTIONS代わりにGET(がAccess-Control-Request-MethodありますGET)。

上記のコードの何が問題になっているのか、またはローカルファイルをデータソースとして使用していない場合に使用して追加のヘッダーを取得する方法はありますか?


2
これはCORSの問題のようです
Kevin Hakanson 2013年

それは確かにCORSの問題でした。サーバーはAccess-Control-Allow-Origin:ヘッダーを返すように構成されていませんでした。コメントとCORSについて少し詳しく回答を書いていただける場合は、その回答を受け付けます。Dmitry Evseevによる以下の回答とあなたが編集した回答は近いものでしたが、実際の問題ではありませんでした。
trentclowater 2013年

1
リクエストがクロスドメインの場合、ChromeはリクエストをプリフライトしてCORSヘッダーを探します。私の答えを確認してください。
Asim KT

回答:


66

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

ブラウザから、またはサーバー上に表示されていませんか?ブラウザツールまたはデバッグプロキシを試し、何が送信されているかを確認します。


サーバーにアクセスできず、ブラウザーでFirefoxを使用していますが、上記の元の質問に追加したヘッダーが表示されています。Chromeの[リソース]タブでヘッダーを表示できる場所がわかりません。
trentclowater 2013年

申し訳ありませんが、元の質問で使用するための編集をあなたの回答に追加しました。
trentclowater 2013年

リソースではなく、開発者ツールのネットワークタブを意味しました-更新の回答
Kevin Hakanson 2013年

質問にさらに情報を追加しました。あるケースではヘッダーが追加され、別のケースでは追加されないようです。
trentclowater 2013年

21

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

最良の答え。
ヨーダ、

9

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

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

OPTIONS以外のすべてのリクエスト
Rocco

良い例です。これを使用して、ページをリダイレクトするためのトークンをキャッシュできますか?
Martian2049 2016

7

私の提案は、適切なヘッダーをチェックする関数内に、このような関数呼び出し設定を追加することです。きっとうまくいくと思います。それは完全に私のために働いています。

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

2

OPTIONSリクエストで表示される内容は問題ありません。承認ヘッダーは公開されていません。

ただし、基本認証を機能させるには、をに追加する必要がありwithCredentials = true;ますvar config

AngularJS $ httpドキュメントから

withCredentials -- XHRオブジェクトにフラグ{boolean}を設定するかどうかwithCredentials。詳細については、認証情報付きのリクエストをご覧ください。


1

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

OPTIONSでは、クライアントはサーバーがCORSリクエストを許可するかどうかをチェックしています。それが204とは異なるものを提供する場合は、正しいAllow-Originヘッダーを送信するようにサーバーを構成する必要があります。

ヘッダーを追加する方法は、それを行う正しい方法です。


1

ChromeはCORSヘッダーを探すリクエストをプリフライトしています。リクエストが受け入れ可能であれば、実際のリクエストを送信します。このクロスドメインを実行している場合は、それに対処するか、リクエストをクロスドメイン以外にする方法を見つける必要があります。これは仕様によるものです。

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

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

参照:GET / POST / PUT / DELETEの代わりにOPTIONSを送信するChromeのAJAX?


-8

私にとっては、次の説明の断片が機能しました。おそらく'、ヘッダー名に使用すべきではありませんか?

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

私はを使用$http.ajax()していますが、これがゲームチェンジャーになるとは思わないでしょう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.