web-dev-qa-db-ja.com

Fetch APIを使用して応答ヘッダーを読み取る

私はGoogle Chrome拡張機能を使用して"*://*/*"の権限を持ち、XMLHttpRequestから Fetch API に切り替えようとしています。

拡張機能は、以前はHTTP AuthのXHRのopen()呼び出しに直接入力されていたユーザー入力ログインデータを格納しますが、Fetchではパラメーターとして直接使用できなくなりました。 HTTP基本認証の場合、Authorizationヘッダーを手動で設定できるため、この制限を回避するのは簡単です。

fetch(url, {
  headers: new Headers({ 'Authorization': 'Basic ' + btoa(login + ':' + pass) })
  } });

HTTPダイジェスト認証 ただし、より多くの対話性が必要です。有効な認証トークンを作成するために、サーバーが401応答とともに送信するパラメーターを読み取る必要があります。このスニペットでWWW-Authenticate応答ヘッダーフィールドを読んでみました:

fetch(url).then(function(resp) {
  resp.headers.forEach(function(val, key) { console.log(key + ' -> ' + val); });
}

しかし、私が得るすべてはこの出力です:

content-type -> text/html; charset=iso-8859-1

これ自体は正しいのですが、Chromeの開発者ツールによると、さらに6つのフィールドが不足しています。 resp.headers.get("WWW-Authenticate")(またはその他のフィールド)を使用すると、nullのみが取得されます。

Fetch APIを使用して他のフィールドにアクセスする可能性はありますか?

41
jules

Fetch API over CORSを使用している場合、応答ヘッダーへのアクセスには制限があります。この制限により、次の標準ヘッダーのみにアクセスできます。

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

Google Chrome拡張機能のコードを書いているときは、 CORS を使用しているため、すべてのヘッダーにアクセスすることはできません。サーバーを制御する場合は、bodyの代わりに応答headersでカスタム情報を返すことができます

この制限の詳細- https://developers.google.com/web/updates/2015/03/introduction-to-fetch#response_types

59
Rajbir Jawanda

MDN から

エントリIteratorにアクセスして、すべてのヘッダーを取得することもできます。

// Display the key/value pairs
for (var pair of res.headers.entries()) {
   console.log(pair[0]+ ': '+ pair[1]);
}

また、覚えておいてください this part:

セキュリティ上の理由から、一部のヘッダーはユーザーエージェントのみが制御できます。これらのヘッダーには、禁止されたヘッダー名と禁止された応答ヘッダー名が含まれます。

7
Avram Tudor

ES2015イテレーターをサポートしないブラウザーとの下位互換性(および、おそらくfetch/Promiseポリフィルも必要)には、Headers.forEach関数が最適なオプションです。

r.headers.forEach(function(value, name) {
    console(name + ": " + value);
});

IE11で、BluebirdをPromiseポリフィルとして、whatwg-fetchをフェッチポリフィルとしてテストしました。 Headers.entries()、Headers.keys()およびHeaders.values()は機能しません。

3

この制限の問題を修正するには、公開されたヘッダー名を追加するだけで十分です。

access-control-expose-headers:headername1、headername2、...

このヘッダーを設定すると、クライアント側のスクリプトは、応答からこれらのヘッダー(headername1、headername2、...)を読み取ることができます。

0
Sheng