JavaScriptを介してページのHTTPレスポンスヘッダにアクセスするにはどうすればよいですか?
この質問に関連しています 、それは2つの特定のHTTPヘッダにアクセスすることについて尋ねるために修正されました。
残念ながら、最初のページリクエストのHTTPレスポンスヘッダを提供するAPIはありません。それがここに投稿された最初の質問でした。他のものを発行せずに元のページリクエストの実際のレスポンスヘッダを取得したいという人もいるので、これは 繰り返し尋ねられる です。
HTTPリクエストがAJAX経由で行われた場合、getAllResponseHeaders()
メソッドでレスポンスヘッダを取得することが可能です。これはXMLHttpRequest APIの一部です。これがどのように適用されるかを見るためには、以下のfetchSimilarHeaders()
関数をチェックしてください。これは問題の回避策であり、アプリケーションによっては信頼できないことに注意してください。
myXMLHttpRequest.getAllResponseHeaders();
APIは、XMLHttpRequestの以下の推奨候補で指定されています。 XMLHttpRequest - W3C勧告候補3 2010年8月
具体的には、以下のセクションでgetAllResponseHeaders()
メソッドが指定されています。 w3.org:XMLHttpRequest
:getallresponseheaders()
メソッド
MDNのドキュメントも良いです: developer.mozilla.org:XMLHttpRequest
。
これは元のページリクエストのHTTPレスポンスヘッダについての情報をあなたに与えることはありませんが、それらのヘッダが何であるかについての知識がある推測をするのに使用することができます。その詳細については次に説明します。
この質問は数年前に最初に尋ねられ、現在のページ(つまりJavaScriptが実行されていたのと同じページ)の元のHTTP応答ヘッダーを取得する方法について具体的に尋ねられました。これはHTTPリクエストのレスポンスヘッダを取得するのとはまったく異なる問題です。最初のページリクエストでは、ヘッダーはJavaScriptですぐには利用できません。 AJAXを介して同じページを再度要求した場合に必要なヘッダー値が確実かつ十分に一貫しているかどうかは、特定のアプリケーションによって異なります。
以下はその問題を回避するためのいくつかの提案です。
レスポンスの大部分が静的で、リクエスト間でヘッダがそれほど変わることが予想されない場合は、現在表示しているのと同じページに対してAJAXリクエストを作成し、それらが同じ値であると想定できます。これはページのHTTPレスポンスの一部でした。これにより、上記のNice XMLHttpRequest APIを使用して必要なヘッダーにアクセスできるようになります。
function fetchSimilarHeaders (callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState === XMLHttpRequest.DONE) {
//
// The following headers may often be similar
// to those of the original page request...
//
if (callback && typeof callback === 'function') {
callback(request.getAllResponseHeaders());
}
}
};
//
// Re-request the same page (document.location)
// We hope to get the same or similar response headers to those which
// came with the current page, but we have no guarantee.
// Since we are only after the headers, a HEAD request may be sufficient.
//
request.open('HEAD', document.location, true);
request.send(null);
}
値が同じであることを完全に保証することはできないので、要求間で値が一致していることに本当に頼らなければならない場合、このアプローチは問題になります。それはあなたの特定のアプリケーションに依存するでしょう、そしてあなたが必要とする価値がある要求から次のものに変わらない何かであることをあなたが知っているかどうか。
いくつかのBOMプロパティ (ブラウザオブジェクトモデル)がブラウザによってヘッダを見て決定されます。これらのプロパティの中にはHTTPヘッダを直接反映するものがあります(例えばnavigator.userAgent
はHTTP User-Agent
ヘッダフィールドの値に設定されます)。利用可能なプロパティを調べれば、必要なものを見つけることができるかもしれませんし、HTTPレスポンスに何が含まれているのかを示す手がかりがあるかもしれません。
サーバー側を制御している場合は、完全な応答を作成するときに好きなヘッダーにアクセスできます。値はページとともにクライアントに渡すことができ、何らかのマークアップで、あるいはおそらくインライン化されたJSON構造で隠すことができます。すべてのHTTPリクエストヘッダをJavaScriptで利用できるようにしたい場合は、それらをサーバ上で繰り返し処理し、それらをマークアップの非表示値として送り返すことができます。この方法でヘッダー値を送信するのはおそらく理想的ではありませんが、必要な特定の値に対して確実に送信できます。この解決策も間違いなく非効率的ですが、必要に応じて仕事をするでしょう。
現在のヘッダを読むことはできません。同じURLに別の要求を出してそのヘッダーを読み取ることもできますが、ヘッダーが現在のものと完全に等しいという保証はありません。
get
リクエストを実行してすべてのHTTPヘッダーを取得するには、次のJavaScriptコードを使用します。
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
alert(headers);
XmlHttpRequest
を使用すると、現在のページをプルアップしてからレスポンスのhttpヘッダーを調べることができます。
最善の方法は、HEAD
リクエストを実行してからヘッダーを調べることです。
これを行ういくつかの例については、 http://www.jibbering.com/2002/4/httprequest.html をご覧ください。
たった2セントです。
サービス担当者は、ヘッダーを含むネットワーク情報にアクセスできます。良いところは、XMLHttpRequestだけでなく、あらゆる種類の要求に対して機能することです。
fetch
関数を使用して、サービスワーカーのrespondWith
を要求にします。postMessage
関数を使用して、サービスワーカーからページにヘッダーを送信します。サービスワーカーは理解するのが少し複雑なので、これをすべて行う小さなライブラリを作成しました。それはgithubで利用可能です: https://github.com/gmetais/sw-get-headers 。
JavaScriptにヘッダー情報を送信するもう1つの方法は、クッキーを使用することです。サーバーは要求ヘッダーから必要なデータを抽出してSet-Cookie
応答ヘッダー内に送り返すことができます。そしてクッキーはJavaScriptで読み取ることができます。しかし、keparoが言っているように、すべてのヘッダに対してではなく、たった1つか2つのヘッダに対してこれを行うのが最善です。
すべてのHTTPヘッダをheaders["content-type"]
という辞書としてアクセスできるオブジェクトに解析する方法を探している人のために、関数parseHttpHeaders
を作成しました。
function parseHttpHeaders(httpHeaders) {
return httpHeaders.split("\n")
.map(x=>x.split(/: */,2))
.filter(x=>x[0])
.reduce((ac, x)=>{ac[x[0]] = x[1];return ac;}, {});
}
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = parseHttpHeaders(req.getAllResponseHeaders());
// Now we can do: headers["content-type"]
Request ヘッダーについて話しているのであれば、XmlHttpRequestを実行するときに独自のヘッダーを作成できます。
var request = new XMLHttpRequest();
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
request.open("GET", path, true);
request.send(null);
Httpヘッダにアクセスすることはできませんが、それらで提供される情報のいくつかはDOMで利用可能です。たとえば、httpリファラ(sic)を見たい場合はdocument.referrerを使用してください。他のhttpヘッダーにはこのような他のものがあるかもしれません。 "http referer javascript"のように、あなたが望む特定のものをグーグルしてみてください。
これは明らかなはずですが、 "http headers javascript"のようなものをリファラーだけで探していて有用な結果が得られなかったときに探し続けました。私はもっと具体的な質問をすることができることに気付かなかったのかどうかわからない。
Mootoolsを使うと、this.xhr.getAllResponseHeaders()を使うことができます。
多くの人のように私は本当の答えなしでネットを掘ってきました:(
それでも私は他の人を助けることができる迂回路を見つけました。私の場合は、Webサーバーを完全に制御します。実際、これは私のアプリケーションの一部です(参考文献を参照)。私のhttpレスポンスにスクリプトを追加するのは簡単です。すべてのHTMLページ内に小さなスクリプトを挿入するようにhttpdサーバーを変更しました。私は自分のブラウザ内で自分のドキュメントから既存の変数を設定するために、私が追加した 'js script'行を私のヘッダ構築直後にプッシュするだけですが、他のオプションも可能です。私のサーバーはnodejsで書かれていますが、PHPや他のものから同じテクニックが使えることは間違いありません。
case ".html":
response.setHeader("Content-Type", "text/html");
response.write ("<script>location['GPSD_HTTP_AJAX']=true</script>")
// process the real contend of my page
今私のサーバーからロードされたすべてのhtmlページは、受付でブラウザによってこのスクリプトを実行させます。変数が存在するかどうかはJavaScriptから簡単に確認できます。私のユースケースでは、CORSの問題を回避するためにJSONまたはJSON-Pプロファイルを使用する必要があるかどうかを知る必要がありますが、同じ手法を他の目的にも使用できます。キーなど
ブラウザでは、私のJson/JQueryプロファイルを選択するために私の例のようにJavaScriptから直接変数をチェックする必要があります。
// Select direct Ajax/Json profile if using GpsdTracking/HttpAjax server otherwise use JsonP
var corsbypass = true;
if (location['GPSD_HTTP_AJAX']) corsbypass = false;
if (corsbypass) { // Json & html served from two different web servers
var gpsdApi = "http://localhost:4080/geojson.rest?jsoncallback=?";
} else { // Json & html served from same web server [no ?jsoncallback=]
var gpsdApi = "geojson.rest?";
}
var gpsdRqt =
{key :123456789 // user authentication key
,cmd :'list' // rest command
,group :'all' // group to retreive
,round : true // ask server to round numbers
};
$.getJSON(gpsdApi,gpsdRqt, DevListCB);
私のコードをチェックしたい人のために: https://www.npmjs.org/package/gpsdtracking
テストしたばかりで、これはChromeバージョン28.0.1500.95を使用している私には有効です。
ファイルをダウンロードしてファイル名を読む必要がありました。ファイル名はヘッダーにあるので、次のようにしました。
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.responseType = "blob";
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
success(xhr.response); // the function to proccess the response
console.log("++++++ reading headers ++++++++");
var headers = xhr.getAllResponseHeaders();
console.log(headers);
console.log("++++++ reading headers end ++++++++");
}
};
出力:
Date: Fri, 16 Aug 2013 16:21:33 GMT
Content-Disposition: attachment;filename=testFileName.doc
Content-Length: 20
Server: Apache-Coyote/1.1
Content-Type: application/octet-stream
より使いやすいオブジェクトとしてヘッダーを取得するには( Raja's answer の改善):
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
headers = headers.split(/\n|\r|\r\n/g).reduce(function(a, b) {
if (b.length) {
var [ key, value ] = b.split(': ');
a[key] = value;
}
return a;
}, {});
console.log(headers);
これは古い質問です。いつサポートがより広くなったか確信していません、しかしgetAllResponseHeaders()
とgetResponseHeader()
は今かなり標準的であるように見えます: http://www.w3schools.com/xml/dom_http.asp