programing

데이터 URL 파일 다운로드

telecom 2023. 9. 7. 21:31
반응형

데이터 URL 파일 다운로드

저는 브라우저에서 누구나 접근할 수 있는 완전히 자바스크립트 기반의 zip/unzip 유틸리티를 만드는 아이디어를 가지고 있습니다.zip을 브라우저로 직접 끌면 파일을 모두 다운로드할 수 있습니다.또한 개별 파일을 끌어와 새 zip 파일을 만들 수도 있습니다.

서버 쪽에서 하는 게 더 낫다는 건 알지만, 이 프로젝트는 단지 약간의 재미를 위해서입니다.

사용 가능한 다양한 방법을 활용한다면 브라우저로 파일을 드래그하는 것이 충분히 쉬울 것입니다. (Gmail 스타일)

부호화/복호화는 괜찮기를 바랍니다.저는 s3 zip 도서관을 몇 군데 본 적이 있어서 괜찮을 것 같습니다.

제 문제는 마지막에 파일을 다운로드하는 것입니다.

window.location = 'data:jpg/image;base64,/9j/4AAQSkZJR....' 

이것은 파이어폭스에서는 잘 작동하지만 크롬에서는 잘 작동하지 않습니다.

크롬으로 파일을 이미지로 잘 내장할 수 있습니다.<img src="data:jpg/image;ba.." />, 하지만 파일이 반드시 이미지일 필요는 없습니다.그들은 어떤 형식이든 될 수 있습니다.

다른 해결책이나 어떤 종류의 해결책을 생각해 낼 수 있는 사람?

(기본 '다운로드' 대신) 파일에 제안된 이름을 지정하려면 Chrome, Firefox 및 일부 IE 버전에서 다음을 사용할 수 있습니다.

function downloadURI(uri, name) {
  var link = document.createElement("a");
  link.download = name;
  link.href = uri;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  delete link;
}

그리고 다음의 예는 그 용도를 보여줍니다.

downloadURI("data:text/html,HelloWorld!", "helloWorld.txt");

function download(dataurl, filename) {
  const link = document.createElement("a");
  link.href = dataurl;
  link.download = filename;
  link.click();
}

download("data:text/html,HelloWorld!", "helloWorld.txt");

또는:

function download(url, filename) {
  fetch(url)
    .then(response => response.blob())
    .then(blob => {
      const link = document.createElement("a");
      link.href = URL.createObjectURL(blob);
      link.download = filename;
      link.click();
  })
  .catch(console.error);
}

download("https://get.geojs.io/v1/ip/geo.json","geoip.json")
download("data:text/html,HelloWorld!", "helloWorld.txt");

아이디어:

  • 해보세요.<a href="data:...." target="_blank">되지 않음으)

  • 데이터 URL 대신 downloadify 사용(IE에서도 사용 가능)

내 경험을 공유하고 Firefox에서 작동하지 않는 다운로드를 계속하는 사람을 돕고 싶고 2014년 답변을 업데이트했습니다.아래 토막글은 파이어폭스와 크롬 모두에서 작동하며 파일 이름을 사용할 수 있습니다.

  // Construct the <a> element
  var link = document.createElement("a");
  link.download = thefilename;
  // Construct the uri
  var uri = 'data:text/csv;charset=utf-8;base64,' + someb64data
  link.href = uri;
  document.body.appendChild(link);
  link.click();
  // Cleanup the DOM
  document.body.removeChild(link);

파이어폭스와 크롬에서는 작동하지만 Internet Explorer에서는 작동하지 않는 순수 자바스크립트 솔루션은 다음과 같습니다.

function downloadDataUrlFromJavascript(filename, dataUrl) {

    // Construct the 'a' element
    var link = document.createElement("a");
    link.download = filename;
    link.target = "_blank";

    // Construct the URI
    link.href = dataUrl;
    document.body.appendChild(link);
    link.click();

    // Cleanup the DOM
    document.body.removeChild(link);
    delete link;
}

지금까지 발견된 크로스 브라우저 솔루션:

downloadify -> 플래시 필요

databounce -> IE 10과 11에서 테스트를 했는데, 나에게는 통하지 않습니다.서블릿과 약간의 커스터마이징이 필요합니다.(Navigator를 잘못 탐지했습니다.IE를 호환성 모드로 설정하여 테스트해야 했고, servlet에 기본 charset을 설정해야 했고, 절대 경로에 대해 정확한 servlet 경로를 가진 JavaScript options object를 설정해야 했습니다...) IE가 아닌 브라우저의 경우 동일한 창에서 파일을 엽니다.

download.js -> http://danml.com/download.html 유사하지만 테스트되지 않은 또 다른 라이브러리서블릿이나 플래시를 필요로 하지 않는 순수한 자바스크립트라고 주장하지만 IE <= 9>에서는 작동하지 않습니다.

몇 가지 해결책이 있지만 HTML5에 의존하며 아직 일부 브라우저에서는 완전히 구현되지 않았습니다.아래 예제들은 Chrome과 Firefox에서 테스트되었습니다(일부 작동됨).

  1. 파일에 저장이 지원되는 캔버스 예제.그냥 당신의 것을.document.location.href데이터 URI로 전송합니다.
  2. 앵커 다운로드 예제.사용합니다.<a href="your-data-uri" download="filename.txt">파일 이름을 지정합니다.

이는 HTML만으로도 100% 완벽하게 해결할 수 있습니다.그냥 설정하세요.href 귀속시키다"data:(mimetypeheader),(url)"를 들면 예를 들면...

<a
    href="data:video/mp4,http://www.example.com/video.mp4"
    target="_blank"
    download="video.mp4"
>Download Video</a>

작동 예: JSFiddle Demo.

Data URL을 사용하기 때문에 다운로드할 데이터의 종류를 나타내는 mim type을 설정할 수 있습니다.설명서:

데이터 URL은 접두사(data:), 데이터 유형을 나타내는 MIME 유형, 텍스트가 아닌 경우 선택적인 base64 토큰, 데이터 자체의 네 부분으로 구성됩니다.(출처 : MDN Web Docs : 데이터 URL)

구성요소:

  • <a ...> 태그 링크 태그.
  • href="data:video/mp4,http://www.example.com/video.mp4"서는 a: A를다한에e에 대한 합니다.data:을리여여리을odhae으로 미리 구성video/mp4 밈유형이 나옵니다. 헤더 밈 유형 다음에 나옵니다.당분간은.txt일,럴 일 입니다.text/plain쉼표가 됩니다. 그런 다음 쉼표로 다운로드할 링크에서 분리합니다.
  • target="_blank": 이것은 새 탭을 열어야 한다는 것을 의미하며, 탭이 필수적인 것은 아니지만 브라우저가 원하는 동작을 수행하도록 안내하는 데 도움이 됩니다.
  • download 다운로드하는 파일의 이름입니다.

@owencm과 @Chazt3n의 답변을 종합하면 IE11, Firefox, Chrome에서 텍스트를 다운로드할 수 있습니다. (죄송합니다. 사파리나 오페라에 접근할 수 없지만 시도해보시면 댓글을 달아주세요.)

initiate_user_download = function(file_name, mime_type, text) {
    // Anything but IE works here
    if (undefined === window.navigator.msSaveOrOpenBlob) {
        var e = document.createElement('a');
        var href = 'data:' + mime_type + ';charset=utf-8,' + encodeURIComponent(text);
        e.setAttribute('href', href);
        e.setAttribute('download', file_name);
        document.body.appendChild(e);
        e.click();
        document.body.removeChild(e);
    }
    // IE-specific code
    else {
        var charCodeArr = new Array(text.length);
        for (var i = 0; i < text.length; ++i) {
            var charCode = text.charCodeAt(i);
            charCodeArr[i] = charCode;
        }
        var blob = new Blob([new Uint8Array(charCodeArr)], {type: mime_type});
        window.navigator.msSaveOrOpenBlob(blob, file_name);
    }
}

// Example:
initiate_user_download('data.csv', 'text/csv', 'Sample,Data,Here\n1,2,3\n');

클릭 시 URL을 즉시 생성하는 버튼(예: Vue 또는 React)에 바인딩하는 경우와 같이 다운로드 작업만 실제로 수행하면 되는 경우 다음과 같이 쉬운 작업을 수행할 수 있습니다.

const link = document.createElement('a')
link.href = url
link.click()

저 같은 경우는 파일 이름이 이미 제대로 되어 있지만 덕분에 설정할 수 있습니다.filename따라서

IE에 문제가 있는 모든 사용자:

dataURItoBlob = function(dataURI) {
    var binary = atob(dataURI.split(',')[1]);
    var array = [];
    for(var i = 0; i < binary.length; i++) {
        array.push(binary.charCodeAt(i));
    }
    return new Blob([new Uint8Array(array)], {type: 'image/png'});
}

var blob = dataURItoBlob(uri);
window.navigator.msSaveOrOpenBlob(blob, "my-image.png");

이 코드는 원래 @Yetti가 이 답변(별도 질문)에 제공한 코드입니다.

파티에 늦게 와서, DOM을 사용하지 않고 기능을 사용하고 싶다면, 어떤 이유로든 DOM을 사용할 수 없을 수도 있기 때문에 시작합니다.

페치 API가 있는 모든 브라우저에서 적용 가능해야 합니다.

여기서 테스트만 하면 됩니다.

// declare the function
function downloadAsDataURL (url) {
  return new Promise((resolve, reject) => {
    fetch(url)
      .then(res => res.blob())
      .then(blob => {
        const reader = new FileReader()
        reader.readAsDataURL(blob)
        reader.onloadend = () => resolve(reader.result)
        reader.onerror = err => reject(err)
      })
      .catch(err => reject(err))
  })
}

// simply use it like this
downloadAsDataURL ('https://cdn-icons-png.flaticon.com/512/3404/3404134.png')
  .then((res) => { 
    console.log(res) 
  })
  .catch((err) => {
    console.error(err) 
  })

당신의 문제는 본질적으로 "모든 브라우저가 이것을 지원하지는 않을 것"으로 귀결됩니다.

해결 방법을 시도하여 플래시 객체에서 압축 해제된 파일을 제공할 수 있지만, 그러면 JS 전용 순도를 잃게 됩니다. (어쨌든 플래시 해결 방법 없이 파일을 브라우저로 끌어다 놓을 수 있는지 모르겠습니다. HTML5 기능이 있을까요?)

export const downloadAs = async (url: string, name: string) => {
  const blob = await axios.get(url, {
    headers: {
      'Content-Type': 'application/octet-stream',
    },
    responseType: 'blob',
  });
  const a = document.createElement('a');
  const href = window.URL.createObjectURL(blob.data);
  a.href = href;
  a.download = name;
  a.click();
};

클린 코드 솔루션을 사용하여 url을 상수로 알려준 후 오브젝트 창 대신 오픈 메서드의 매개 변수로 설정할 수 있습니다.

const url = "file url here"

window.open(url)

언급URL : https://stackoverflow.com/questions/3916191/download-data-url-file

반응형