programing

Ajax - 다운로드 전 파일 크기 가져오기

linuxpc 2023. 8. 4. 22:43
반응형

Ajax - 다운로드 전 파일 크기 가져오기

기본적으로 파일 크기에 따라 AJAX를 사용하여 파일을 다운로드해야 하는지 알고 싶습니다.

이 질문은 "Ajax 요청의 헤더만 가져오려면 어떻게 해야 합니까?"로 대체될 수도 있을 것 같습니다.


편집: 댓글에 있는 ultima-rat0은 이미 질문을 받은 두 가지 질문에 대해 분명히 이 질문과 같습니다.그들은 매우 비슷하지만 둘 다 jQuery를 원합니다.나는 이것에 대한 비jQuery 솔루션을 원합니다.

XHR 응답 헤더 데이터를 수동으로 가져올 수 있습니다.

http://www.w3.org/TR/XMLHttpRequest/ #get-the-get 응답 헤더(1920-1987)

이 함수는 요청된 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와 다르게 행동할 수 있기 때문에 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 요청이 불가능한 경우:

파이어폭스에서 중단된 요청에 컨텍스트 길이를 사용할 수 없었기 때문에 솔루션 에브라힘은 파이어폭스에서만 작동하지 않았습니다.그래서 'onready state change' 이벤트 대신 '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();
  }
);

헤더만 필요한 경우에는 단순하지만 널리 알려지지 않은 세부 정보 때문에 항상 'HEAD'를 'GET'보다 선호해야 합니다.'GET'을 사용하고 readyState === 2에서 즉시 중단하더라도(다른 답변에서 제안한 바와 같이) 헤더뿐만 아니라 크기가 달라질 수 있는 전체 첫 번째 정보 청크(몸통 + 부분)를 이미 수신했을 뿐만 아니라 일반적으로 전송 크기가 불필요하게 두 배 이상 증가합니다.대신 'HEAD'를 사용하면 헤더만 전송됩니다.

클라이언트 측에서 액세스할 수 있으려면 '액세스-제어-노출-헤더'에 의해 내용 길이 헤더가 노출되어야 합니다.여러 오리진 리소스를 처리하는 경우 예외를 방지하기 위해 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));
    }));
}

일부 주석에서 제안한 대로 모든 유형의 인코딩이 적용될 때 내용 길이 헤더는 금지되지 않습니다.그러나 내용 길이는 일반적으로 디코딩된 본문의 크기가 됩니다(비록 그렇지 않더라도).이 문제는 여러 가지 방법으로 방지할 수 있지만 서버 측에서 고려해야 할 사항입니다.

언급URL : https://stackoverflow.com/questions/17416274/ajax-get-size-of-file-before-downloading

반응형