私は、サードパーティのサイトに含まれる JavaScript クライアントを作成しています (Facebook のようなボタンを考えてください)。基本的な HTTP 認証を必要とする API から情報を取得する必要があります。単純化されたセットアップは次のようになります。
サードパーティのサイトには、ページに次のスニペットが含まれています。
<script
async="true"
id="web-dev-widget"
data-public-key="pUbl1c_ap1k3y"
src="http://web.dev/widget.js">
</script>
widget.jsは API を呼び出します。
var el = document.getElementById('web-dev-widget'),
user = 'token',
pass = el.getAttribute('data-public-key'),
url = 'https://api.dev/',
httpRequest = new XMLHttpRequest(),
handler = function() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
console.log(httpRequest.responseText);
} else {
console.log('There was a problem with the request.', httpRequest);
}
}
};
httpRequest.open('GET', url, true, user, pass);
httpRequest.onreadystatechange = handler;
httpRequest.withCredentials = true;
httpRequest.send();
API は、適切なヘッダーで応答するように構成されています。
Header set Access-Control-Allow-Credentials: true
Header set Access-Control-Allow-Methods: "GET, OPTIONS"
Header set Access-Control-Allow-Headers: "origin, authorization, accept"
SetEnvIf Origin "http(s)?://(.+?\.[a-z]{3})$" AccessControlAllowOrigin=$0
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
認証済みの要求 ( ) を送信しているため、ワイルドカードを使用する代わりにAccess-Control-Allow-Origin
が に設定されていることに注意してください。Origin
withCredentials
これで、非同期のクロスドメイン認証リクエストを作成するための準備が整いました。これは、OS X 10.8.2 の Chrome 25 でうまく機能します。Dev Tools では、リクエストのOPTIONS
前にGET
リクエストのネットワーク リクエストを確認でき、期待どおりにレスポンスが返ってきます。
Firefox 19 でテストすると、ネットワーク リクエストが Firebug に API に表示されず、次のエラーがコンソールに記録されます。NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
いろいろ調べた結果、コメントによると、Gecko ではユーザー名とパスワードをクロスサイト URI に直接入れることを許可していないことがわかりました。これは、オプションのユーザーとパスワードのパラメーターを使用したことが原因であると想定したopen()
ため、資格情報を Base64 でエンコードし、Authorization ヘッダーで送信するという認証済みの要求を作成する別の方法を試しました。
// Base64 from http://www.webtoolkit.info/javascript-base64.html
auth = "Basic " + Base64.encode(user + ":" + pass);
...
// after open() and before send()
httpRequest.setRequestHeader('Authorization', auth);
これにより、Google 検索につながるリクエスト401 Unauthorized
への応答が返されます。OPTIONS
その時、私は自分が困っていることを知りました。
Firefox ではなく Chrome で機能するのはなぜですか? OPTIONS
要求を一貫して送信および応答するにはどうすればよいですか?