development

링크가없는 JavaScript Blob 파일 이름

big-blog 2020. 6. 9. 07:46
반응형

링크가없는 JavaScript Blob 파일 이름


window.location을 통해 강제로 다운로드 할 때 JavaScript에서 Blob 파일의 이름을 어떻게 설정합니까?

function newFile(data) {
    var json = JSON.stringify(data);
    var blob = new Blob([json], {type: "octet/stream"});
    var url  = window.URL.createObjectURL(blob);
    window.location.assign(url);
}

위 코드를 실행하면 다음과 같은 페이지 새로 고침없이 파일이 즉시 다운로드됩니다.

bfefe410-8d9c-4883-86c5-d76c50a24a1d

대신 파일 이름을 my-download.json 으로 설정하고 싶습니다 .


내가 아는 유일한 방법은 FileSaver.js가 사용하는 트릭입니다 .

  1. 숨겨진 <a>태그를 만듭니다 .
  2. 해당 href속성을 Blob의 URL로 설정하십시오 .
  3. download속성을 파일 이름으로 설정하십시오 .
  4. <a>태그를 클릭하십시오 .

다음은 간단한 예입니다 ( jsfiddle ).

var saveData = (function () {
    var a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    return function (data, fileName) {
        var json = JSON.stringify(data),
            blob = new Blob([json], {type: "octet/stream"}),
            url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = fileName;
        a.click();
        window.URL.revokeObjectURL(url);
    };
}());

var data = { x: 42, s: "hello, world", d: new Date() },
    fileName = "my-download.json";

saveData(data, fileName);

아이디어를 설명하기 위해이 예제를 작성했습니다. 프로덕션 코드에서는 FileSaver.js를 대신 사용하십시오.

노트

  • 이전 브라우저는 HTML5의 일부이므로 "다운로드"속성을 지원하지 않습니다.
  • 일부 파일 형식은 브라우저에서 안전하지 않은 것으로 간주되어 다운로드가 실패합니다. txt 확장자로 JSON 파일을 저장하면 효과적입니다.

Internet Explorer (대부분 최신 버전)를 지원하여 허용되는 답변을 확장하고 jQuery를 사용하여 코드를 정리하고 싶었습니다.

$(document).ready(function() {
    saveFile("Example.txt", "data:attachment/text", "Hello, world.");
});

function saveFile (name, type, data) {
    if (data !== null && navigator.msSaveBlob)
        return navigator.msSaveBlob(new Blob([data], { type: type }), name);
    var a = $("<a style='display: none;'/>");
    var url = window.URL.createObjectURL(new Blob([data], {type: type}));
    a.attr("href", url);
    a.attr("download", name);
    $("body").append(a);
    a[0].click();
    window.URL.revokeObjectURL(url);
    a.remove();
}

여기 Fiddle의 예가 있습니다. Godspeed .


위의 솔루션과 동일한 원칙. 그러나 큰 파일 (> 40MB)이 임의 위치에서 잘리는 Firefox 52.0 (32 비트)에 문제가있었습니다. revokeObjectUrl () 호출을 다시 예약하면이 문제가 해결됩니다.

function saveFile(blob, filename) {
  if (window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(blob, filename);
  } else {
    const a = document.createElement('a');
    document.body.appendChild(a);
    const url = window.URL.createObjectURL(blob);
    a.href = url;
    a.download = filename;
    a.click();
    setTimeout(() => {
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);
    }, 0)
  }
}

늦었지만 같은 문제가 있었으므로 솔루션을 추가했습니다.

function newFile(data, fileName) {
    var json = JSON.stringify(data);
    //IE11 support
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        let blob = new Blob([json], {type: "application/json"});
        window.navigator.msSaveOrOpenBlob(blob, fileName);
    } else {// other browsers
        let file = new File([json], fileName, {type: "application/json"});
        let exportUrl = URL.createObjectURL(file);
        window.location.assign(exportUrl);
        URL.revokeObjectURL(exportUrl);
    }
}

saveFileOnUserDevice = function(file){ // content: blob, name: string
        if(navigator.msSaveBlob){ // For ie and Edge
            return navigator.msSaveBlob(file.content, file.name);
        }
        else{
            let link = document.createElement('a');
            link.href = window.URL.createObjectURL(file.content);
            link.download = file.name;
            document.body.appendChild(link);
            link.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));
            link.remove();
            window.URL.revokeObjectURL(link.href);
        }
    }

예를 들어 작업 "cat.jpg"와 같은 URL에서 고양이 사진을 저장, 다운로드 버튼의 :

HTML :

<button onclick="downloadUrl('https://i.imgur.com/AD3MbBi.jpg', 'cat.jpg')">Download</button>

JavaScript:

function downloadUrl(url, filename) {
  let xhr = new XMLHttpRequest();
  xhr.open("GET", url, true);
  xhr.responseType = "blob";
  xhr.onload = function(e) {
    if (this.status == 200) {
      const blob = this.response;
      const a = document.createElement("a");
      document.body.appendChild(a);
      const blobUrl = window.URL.createObjectURL(blob);
      a.href = blobUrl;
      a.download = filename;
      a.click();
      setTimeout(() => {
        window.URL.revokeObjectURL(blobUrl);
        document.body.removeChild(a);
      }, 0);
    }
  };
  xhr.send();
}

window.location.assign did not work for me. it downloads fine but downloads without an extension for a CSV file on Windows platform. The following worked for me.

    var blob = new Blob([csvString], { type: 'text/csv' });
    //window.location.assign(window.URL.createObjectURL(blob));
    var link = window.document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    // Construct filename dynamically and set to link.download
    link.download = link.href.split('/').pop() + '.' + extension; 
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);

참고URL : https://stackoverflow.com/questions/19327749/javascript-blob-filename-without-link

반응형