data : URI를 사용할 때 제안 된 파일 이름을 지정하는 방법이 있습니까?


225

예를 들어 링크를 따라 가면

data:application/octet-stream;base64,SGVsbG8=

브라우저는 하이퍼 링크 자체에서 base64로 보관 된 데이터로 구성된 파일을 다운로드하라는 메시지를 표시합니다. 마크 업에서 기본 이름을 제안하는 방법이 있습니까? 그렇지 않은 경우 JavaScript 솔루션이 있습니까?


이 문제와 관련이 없지만 서버 또는 오래된 브라우저 장애가 아닌 경우 blob의 & URL.createObjectURL을 사용하는 것이 좋습니다.
Endless

3
일부 브라우저는 data:application/pdf;name=document.pdf;base64,BASE64_DATA_ENCODED
미디어 유형

Firefox pdf.js에 문제가있어서 데이터 URI에서 파일 이름을 추출 할 수없는 경우 중단되는 경우가 있습니다. 참조 stackoverflow.com/questions/45585921/...
베른하르트

@mems "name"매개 변수를 지원하는 브라우저는 무엇입니까? 참조 문서를 알려 주시겠습니까? (내 google-fu가 실패했습니다).
TheAddonDepot

@DimuDesigns 그 당시에는 최소한 Firefox입니다. 더 이상 그렇지 않은 것 같습니다. MIME Content-Type (! = Content-Disposition) "name"매개 변수와 관련이 있습니다 (RFC가 아닙니까?)
mems

답변:


158

download속성을 사용하십시오 .

<a download='FileName' href='your_url'>

에 라이브 예를 html5-demos.appspot.com / ... .

현재 Chrome, Firefox, Edge, Opera 및 데스크톱 Safari에서는 작동하지만 iOS Safari 또는 IE11에서는 작동하지 않습니다.


3
@ BioDesign : 그것은 데이터와 함께 작동합니다 : URI의 크롬입니다. 참조 : jsfiddle.net/pYpqW
Senseful

6
하지만 당신은 그것을 할 수 없습니다 window.location.replace. 예를 들어 data : uri 또는로 생성 된 데이터를 생성하고이를 window.URL.createObjectURL파일로 다운로드하려면 <a>를 생성하고 클릭해야합니다. jsfiddle.net/flyingsheep/wpQtH (아니, $(...).click()작동하지 않습니다)
비행 양

1
모든 브라우저가 Chrome과 같은 경우에만 ... [sigh]
streetlight

6
@ flyingsheep $('<a href="data:text/plain,Test" download="test.txt">')[0].click()는 여기서 잘 작동하는 것 같습니다 (Chrome 23) (참고 : jQuery가 아닌 기본 click메소드를 사용했습니다 ). 데모 : jsfiddle.net/2zsRW
Rob W

1
@flyingsheep Firefox에서 동일한 출처 정책을 시행하는 것 같습니다. "Firefox 20에서이 속성은 동일한 출처를 가진 자원에 대한 링크에만 적용됩니다." developer.mozilla.org/en-US/docs/Web/HTML/Element/a 내 테스트에서 Chrome에는이 제한이 없습니다.
William Denniss

62

요즘 크롬은 이것을 매우 간단하게 만듭니다.

function saveContent(fileContents, fileName)
{
    var link = document.createElement('a');
    link.download = fileName;
    link.href = 'data:,' + fileContents;
    link.click();
}

이 모든 다른 답변에 대한 이야기는 Chrome 30에서 처음 시도한 결과입니다.
Michael J. Calkins

2
지금은 그렇지만 항상 그렇게 쉬운 것은 아닙니다. 이러한 답변 중 많은 부분이 몇 년 전에 나온 것입니다. 또한 다른 브라우저에서도 작동합니다.
Holf

7
브라우저 호환성의 전체 목록은 http://caniuse.com/#feat=download 를 참조하십시오 .
tixastronauta 2013

2
@tixastronauta : 해당 페이지의 정보에도 불구하고 내 firefox 44에서 작동하지 않습니다. Chrome에서 잘 작동합니다. 48
Luis A. Florit

안녕 @ Holf 파일 형식이나 확장명처럼 파일 형식이나 확장명을 추가하는 방법이 있습니까?
Fraccier

51

HTML 만 해당 :download 속성을 사용하십시오 .

<a download="logo.gif" href="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">Download transparent png</a>


자바 스크립트 만 해당 : 이 코드를 사용하여 모든 데이터 URI를 저장할 수 있습니다.

function saveAs(uri, filename) {
  var link = document.createElement('a');
  if (typeof link.download === 'string') {
    link.href = uri;
    link.download = filename;

    //Firefox requires the link to be in the body
    document.body.appendChild(link);
    
    //simulate click
    link.click();

    //remove the link when done
    document.body.removeChild(link);
  } else {
    window.open(uri);
  }
}

var file = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
saveAs(file, 'logo.gif');

Chrome, Firefox 및 Edge 13+ 는 지정된 파일 이름을 사용합니다.

IE11, 에지 (12), 사파리 (9)는 (이 지원하지 않는 download속성 ) 기본 이름을 사용하여 파일을 다운로드합니다 또는 그들은 단순히 그것을 표시 가 지원되는 파일 유형의 경우, 새 탭에서 : 이미지, 동영상, 오디오 파일을 …


두 데모 모두 Chrome 38에서 제대로 작동하지만 Chrome 14 이상에서는 작동해야합니다.
fregante

보다 완벽한 솔루션을 위해, 내가 사용하는 것이 좋습니다 downloadjsNPM에
fregante

그것은 나를 위해 작동하지만 그 후에 브라우저 페이지가 새로 고쳐집니다. 그것을 막는 방법이 궁금하십니까?

1
Chrome에서 파일 크기가 2MB를
초과

제한은 data:URI에 속하며 질문에서 언급 한 것입니다. 이 답변은 물방울로 작동하고 어떤 다른 URI를 가지고
fregante

40

RFC 2397 에 따르면 , 없습니다.

어느 쪽이든 사용할 수 있는 요소의 속성 이없는 것 같습니다 <a>.

그러나 HTML5는 지원을 작성하는 시점에 보편적이지 않지만 (예를 들어 MSIE 지원이 아님) 요소에 download속성을 도입했습니다.<a>


9
두 번째 문장은 글을 쓰는 시점에 옳았지만 더 이상 그렇지 않습니다 . 현재로서는 아직 널리 구현되지 않았습니다.
날으는 양

자세한 내용은 이 의견 을 참조하십시오 :)
날으는 양

@flyingsheep, 그것은 되어 널리 구현했습니다.
Pacerier

1
내가 그 댓글을 쓰셨 때 3 년 전의 일이 아니다
비행 양을

파일이 너무 길면 다운로드가 실패합니다
deFreitas

21

netwerk / protocol / data / nsDataHandler.cpp의 파이어 폭스 소스에서 조금 보았습니다.

Data Handler는 내용 / 유형 및 문자 세트 만 구문 분석하고 문자열에 "; base64"가 있는지 확인합니다.

rfc는 파일 이름을 지정하지 않으며 최소한 firefox는 파일 이름을 처리하지 않습니다. 코드는 임의의 이름에 ".part"를 추가합니다.

파이어 폭스 로그도 확인했습니다.

[b2e140]: DOCSHELL 6e5ae00 InternalLoad data:application/octet-stream;base64,SGVsbG8=
[b2e140]: Found extension '' (filename is '', handling attachment: 0)
[b2e140]: HelperAppService::DoContent: mime 'application/octet-stream', extension ''
[b2e140]: Getting mimeinfo from type 'application/octet-stream' ext ''
[b2e140]: Extension lookup on '' found: 0x0
[b2e140]: Ext. lookup for '' found 0x0
[b2e140]: OS gave back 0x43609a0 - found: 0
[b2e140]: Searched extras (by type), rv 0x80004005
[b2e140]: MIME Info Summary: Type 'application/octet-stream', Primary Ext ''
[b2e140]: Type/Ext lookup found 0x43609a0

모질라 소스를보고 싶다면 흥미로운 파일 :

data uri handler: netwerk/protocol/data/nsDataHandler.cpp
where mozilla decides the filename: uriloader/exthandler/nsExternalHelperAppService.cpp
InternalLoad string in the log: docshell/base/nsDocShell.cpp

나는 당신이 해결책을 찾지 않을 수 있다고 생각합니다.

이 스레드에서 알 수 있듯이 html5는 download속성을 가지고 있으며 firefox 20에서도 작동합니다 .


3
멋있는! Firefox가 존재하는 것에 대한 궁극적 인 권위라는 데 반드시 동의하는 것은 아닙니다. :)
Gleno

14

다음 자바 스크립트 스 니펫은 링크의 새로운 '다운로드'속성을 사용하고 클릭을 시뮬레이션하여 Chrome에서 작동합니다.

function downloadWithName(uri, name) {
  var link = document.createElement("a");
  link.download = name;
  link.href = uri;
  link.click();
}

그리고 다음 예제는 그 사용법을 보여줍니다.

downloadWithName("data:,Hello%2C%20World!", "helloWorld.txt")

1
Firefox에서는 작동하지 않습니다. Fx 호환성으로 아래에 확장 된 답변을 추가했습니다.
fregante

12

아니.

전체 목적은 파일이 아니라 데이터 스트림이라는 것입니다. 데이터 소스는 파일로 파일을 처리하는 사용자 에이전트에 대한 지식이 없어야합니다.


6
내부 데이터 data:블록을 프로토콜 기반 소스에서 읽을 필요없이 URL 형식으로 퍼지하는 것이 목적입니다 . @silex의 답변에있는 링크는 선호하는 이름을 도록 제안하는 기능이 아직 구현되지 않았더라도 유용하다고 간주됩니다.
Alnitak

1
@Alnitak : 유용합니까? 물론. 기술적으로 적절합니까? 아직 확신하지 못했습니다. :)
궤도에서 가벼움 레이스

3
@Tomalak은 데이터를로드하고 저장하는 것의 차이점을 고려합니다. 블롭은 데이터에 인라인으로 인코딩되기 때문에 URL은 데이터를 저장하기 위해 선호하는 이름이 없어야한다는 의미는 아닙니다.
Alnitak

4
그러나 "전체 목적"에 대한 귀하의 선은 잘못되었습니다. data:은 (작은) 인라인 컨텐츠를 퍼지 된 URL 형식으로 표시하여 별도의 HTTP 요청없이 이미지 태그와 같은 것들에 의해 사용될 수 있도록 하기 위해 특별히 고안되었습니다 . HTML은 img src속성 의 내용이 URL이어야하므로 RFC 2397이 생성 한 것이라고 말합니다 . "데이터 소스"가 없습니다.
Alnitak

6
@Alnitak : 맞습니다. 데이터 소스가 없습니다. 문맥이 없습니다. URI 데이터입니다.
궤도에서 가벼움 레이스

9

앵커 요소에 다운로드 속성을 추가 할 수 있습니다.

견본:

<a download="abcd.cer"
    href="data:application/stream;base64,MIIDhTC......">down</a>

5

이 링크를보십시오 : http://lists.w3.org/Archives/Public/uri/2010Feb/0069.html

인용문:

;
최소한 Opera에서 다음과 같이 ; base64와 함께 작동합니다 (문제가 발생하지 않습니다 ).

data : text / plain; charset = utf-8; headers = 콘텐츠 배치 % 3A % 20 첨부 파일 % 3B % 20filename % 3D % 22with % 20spaces.txt % 22 % 0D % 0AContent-Language % 3A % 20en; base64,4oiaDQo % 3D

또한 토론의 나머지 메시지에 일부 정보가 있습니다.


불행히도 이것은 다운로드되지 않습니다.
James Khoury

7
이 논의는 데이터 URI 형식 에 대한 제안 된 확장에 대한 것이지만 구현되지 않았습니다.
Alnitak

구현 여부에 관계없이 임의의 매개 변수에 대한 기존 지원을 사용하면 이것이 좋습니다.
Dan Lugg

5

서비스 워커를 사용하면 이것이 진정한 의미에서 마침내 가능합니다.

  1. 가짜 URL을 만듭니다. 예를 들어 /saveAs/myPrettyName.jpg
  2. <a href, <img src"실제"URL로 수행 할 수있는 모든 것, window.open (url)에 URL을 사용하십시오 .
  3. 작업자 내부에서 페치 이벤트를 포착하고 올바른 데이터로 응답하십시오.

브라우저는 이제 사용자가 새 탭에서 파일을 열어 저장하려고해도 myPrettyName.jpg를 제안합니다. 파일이 서버에서 온 것처럼 정확하게됩니다.

// In the service worker
self.addEventListener( 'fetch', function(e)
{
    if( e.request.url.startsWith( '/blobUri/' ) )
    {
        // Logic to select correct dataUri, and return it as a Response
        e.respondWith( dataURLAsRequest );
    }
});

1
흥미 롭습니다! 지원은 현재 매우 얕아 보입니다 : caniuse.com/#feat=serviceworkers
tuomassalo

파일에 대한 다른 직접 URL로 "응답"할 수있는 방법이 있습니까?
Iulian Onofrei

4

Google 코드에는 나를 위해 일한 작은 해결 방법 스크립트가 있습니다.

http://code.google.com/p/download-data-uri/

데이터가 포함 된 양식을 추가하고 제출 한 다음 양식을 다시 제거합니다. 해키, 그러나 그것은 나를 위해 일을했다. jQuery가 필요합니다.

이 스레드는 Google 코드 페이지 이전에 Google에 나타 났으며 여기에 링크가 있으면 도움이 될 것이라고 생각했습니다.


재미있는 스크립트이지만 서버가 응답을 얻으려면 다시 보내야합니까? jsfiddle.net/hZySf
James Khoury

파일이 어디에서 생성되는지 잘 모르겠습니다. 해당 파일이 base64 인코딩으로 저장되어 있습니까? (저는 base64에 익숙하지 않습니다)
가로등

@streetlight : "파일"(즉, 데이터)은 Javascript에 의해 생성됩니다. 해당 프로젝트의 컨텍스트 (및 아마도 대부분의 경우)는 원하는 데이터를 JS 변수로 가져 오는 방법이 있다고 가정합니다. 차이점은 data:...URI 를 통해 사용자에게 제공하는 대신 스크립트가 서버에 POST하는 양식을 작성한다는 것입니다. 그런 다음 서버는 아마도 HTTP "다운로드"응답 (즉, 파일 이름을 지정하는 적절한 Content-Disposition 헤더를 사용하여)으로 바로 다시 에코합니다.
Andrzej Doyle

4

다음은 Holf 버전을 기반으로 한 jQuery 버전이며 Chrome 및 Firefox에서 작동하지만 그의 버전은 Chrome에서만 작동하는 것으로 보입니다. 이 작업을 수행하기 위해 몸에 무언가를 추가하는 것은 약간 이상하지만 누군가 더 나은 옵션이 있다면 나는 그게 전부입니다.

var exportFileName = "export-" + filename;
$('<a></a>', {
    "download": exportFileName,
    "href": "data:," + JSON.stringify(exportData, null,5),
    "id": "exportDataID"
}).appendTo("body")[0].click().remove();

1
jQuery 1.11에서는 .remove () 때문에 예외가 발생합니다. 나는 할당하여이 문제를 가지고 $().appendTo()다음 변수에 호출variable.click(); variable.remove()
p0lar_bear

@ p0lar_bear [0]"jQuery 요소"에서 가져 오는 것이 표시하는 첫 번째 DOM 요소를 반환해야 하므로 jQuery에서 예외를 가져와야합니다 .
drzaus

실제로 요소를 추가 / 제거 할 필요는 없습니다. stackoverflow.com/a/17311705/1037948의
drzaus

3

일종의 해킹이지만 이전과 같은 상황에있었습니다. Javascript에서 동적으로 텍스트 파일을 생성하고 data-URI로 인코딩하여 다운로드를 제공하려고했습니다.

이는 사소한 주요 사용자 개입으로 가능합니다. 링크를 생성하십시오 <a href="data:...">right-click me and select "Save Link As..." and save as "example.txt"</a>. 내가 말했듯이, 이것은 우아하지 않지만 전문적인 솔루션이 필요하지 않은 경우 작동합니다.

플래시를 사용하여 이름을 클립 보드에 먼저 복사하면 고통이 줄어 듭니다. 물론 플래시 또는 Java를 사용하게한다면 (지금은 브라우저 지원이 점점 줄어들고 있다고 생각하십니까?)이를 수행하는 다른 방법을 찾을 수 있습니다.


이것은 해결책이 아니며 요청한 내용을 충족하지 않습니다. 죄송합니다.
jcolebrand

7
"사소한 사용자 개입"@ Lol. 사용자가 당신을 위해 모든 것을하게하는 것은 "사소한 사용자 개입"이 아닙니다.
궤도에서 가벼움 레이스

이것을 stackoverflow.com/questions/17311645/… 와 결합 하여 생성 된 링크를 트리거하므로 사용자 개입이 필요하지 않습니다. HTML5 download속성 을 지정하여 다른 많은 답변에서 언급 한대로 이름을 제안 할 수 있습니다 .
drzaus

이것은 Safari에 대한 훌륭한 해결 방법입니다. Modernizr을 사용하여 다운로드 속성이 지원되지 않는시기를 감지하고 링크 텍스트를 업데이트하십시오!
littledynamo 2016 년

2

이것은 Firefox 43.0 (이전 버전은 테스트되지 않음)에서 작동합니다.

dl.js :

function download() {
  var msg="Hello world!";
  var blob = new File([msg], "hello.bin", {"type": "application/octet-stream"});

  var a = document.createElement("a");
  a.href = URL.createObjectURL(blob);

  window.location.href=a;
}

dl.html

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="utf-8"/>
    <title>Test</title>
    <script type="text/javascript" src="dl.js"></script>
</head>

<body>
<button id="create" type="button" onclick="download();">Download</button>
</body>
</html>

버튼을 클릭하면 hello.bin 이라는 파일이 제공됩니다 . 트릭은 Blob 대신 File 을 사용하는 것입니다 .

참조 : https://developer.mozilla.org/de/docs/Web/API/File


0
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
var sessionId ='\n';
var token = '\n';
var caseId = CaseIDNumber + '\n';
var url = casewebUrl+'\n';
var uri = sessionId + token + caseId + url;//data in file
var fileName = "file.i4cvf";// any file name with any extension
if (isIE)
    {
            var fileData = ['\ufeff' + uri];
            var blobObject = new Blob(fileData);
            window.navigator.msSaveOrOpenBlob(blobObject, fileName);
    }
    else //chrome
    {
        window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
         window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function (fs) {
            fs.root.getFile(fileName, { create: true }, function (fileEntry) { 
                fileEntry.createWriter(function (fileWriter) {
                    var fileData = ['\ufeff' + uri];
                    var blob = new Blob(fileData);
                    fileWriter.addEventListener("writeend", function () {
                        var fileUrl = fileEntry.toURL();
                        var link = document.createElement('a');
                        link.href = fileUrl;
                        link.download = fileName;
                        document.body.appendChild(link);
                        link.click();
                        document.body.removeChild(link);
                    }, false);
                    fileWriter.write(blob);
                }, function () { });
            }, function () { });
         }, function () { });
    }

1
pls는 당신의 대답에 대한 자세한 설명을 추가 - stackoverflow.com/help/how-to-answer
세바스찬 Brosch

1
이 답변은 쓰레기입니다
Jonathan Taylor

-2

실제로 Chrome과 FireFox에서이를 달성 할 수 있습니다.

다음 URL을 시도하면 사용 된 코드가 다운로드됩니다.

data:text/html;base64,PGEgaHJlZj0iZGF0YTp0ZXh0L2h0bWw7YmFzZTY0LFBHRWdhSEpsWmowaVVGVlVYMFJCVkVGZlZWSkpYMGhGVWtVaUlHUnZkMjVzYjJGa1BTSjBaWE4wTG1oMGJXd2lQZ284YzJOeWFYQjBQZ3BrYjJOMWJXVnVkQzV4ZFdWeWVWTmxiR1ZqZEc5eUtDZGhKeWt1WTJ4cFkyc29LVHNLUEM5elkzSnBjSFErIiBkb3dubG9hZD0idGVzdC5odG1sIj4KPHNjcmlwdD4KZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYScpLmNsaWNrKCk7Cjwvc2NyaXB0Pg==
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.