基本的に、ファイルサイズの大きさに応じて、AJAXを使用してファイルをダウンロードする必要があるかどうかを判断したいと思います。
この質問は次のように言い換えることもできると思います:ajaxリクエストのヘッダーのみを取得するにはどうすればよいですか?
[〜#〜] edit [〜#〜]: ltima-rat コメントで2つの質問がありましたどうやらこれと同じだとすでに聞かれました。それらは非常に似ていますが、どちらもjQueryを必要としています。これに対する非jQueryソリューションが必要です。
XHR応答ヘッダーデータを手動で取得できます。
http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
この関数は、要求されたURLのファイルサイズを取得します。
function get_filesize(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open("HEAD", url, true); // Notice "HEAD" instead of "GET",
// to get only the header
xhr.onreadystatechange = function() {
if (this.readyState == this.DONE) {
callback(parseInt(xhr.getResponseHeader("Content-Length")));
}
};
xhr.send();
}
get_filesize("http://example.com/foo.exe", function(size) {
alert("The size of foo.exe is: " + size + " bytes.");
});
HEADはGETとは異なる動作をする可能性があるため、Content-Length
ヘッダーを取得した後にリクエストを中止する次のようなものを提案します。
new Promise(resolve => {
var xhr = new XMLHttpRequest();
xhr.open('GET', '/a.bin', true);
xhr.onreadystatechange = () => {
resolve(+xhr.getResponseHeader("Content-Length"));
xhr.abort();
};
xhr.send();
}).then(console.log);
HEADリクエストが不可能な場合:
Ebrahimの解決策は、Firefoxで中止された要求にcontext-lengthが使用できないため、Firefoxでは機能しませんでした。そのため、「onreadystatechange」イベントの代わりに「onprogress」イベントを使用しました。
new Promise(
(resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onprogress = (event) => {
if (event.lengthComputable) {
resolve(event.total);
} else {
reject(new Error('No content-length available'));
}
xhr.abort();
};
xhr.send();
}
);
1)ヘッダーのみが必要な場合は、詳細が単純であるが広く知られていないため、「GET」よりも「HEAD」を常に優先する必要があります。回答)、ヘッダーだけでなく、サイズが異なる可能性のある情報の最初のチャンク全体(ヘッダー+本文の一部)をすでに受信していますが、通常、転送サイズは少なくとも不必要に2倍になります。代わりに「HEAD」を使用すると、ヘッダーのみが転送されることを確認できます。
2)Content-Lengthヘッダーは、クライアント側でアクセスできるように、「Access-Control-Expose-Headers」によって公開される必要があります。複数のOriginリソースを処理していて、Content-Lengthが公開されているかどうかわからない場合は、例外を防ぐために、次のように(または他の多くの異なる方法で)イベントハンドラー内で確認できます。
let contentLength = null;
if (checkHeaders(e.target, ['*','Content-Length'])) {
// YOU CAN ACCESS HEADER
contentLength = parseInt(e.target.getResponseHeader("Content-Length"));
} else {
// YOU CAN NOT ACCESS HEADER
console.log('Content-Length NOT AVAILABLE');
}
function checkHeaders(request, headers) {
return (headers.some(function (elem) {
return (request.getResponseHeader("Access-Control-Expose-Headers").includes(elem));
}));
}
3)Content-LengthヘッダーIS任意のタイプのエンコーディングが適用される場合は禁止されません(一部のコメントで示唆されているように)。ただし、Content-Lengthは通常、デコードされた本文のサイズになることに注意してください。 (そうでない場合でも)これはさまざまな方法で防ぐことができますが、サーバー側の考慮事項です。