2008-11-12 3 views
197

Если, например, по ссылке:Есть ли способ указать предлагаемое имя файла при использовании данных: URI?

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

Браузер предложит вам скачать файл, состоящий из данных, содержащихся в base64 в самой гиперссылке. Есть ли способ предложить имя по умолчанию в разметке? Если нет, есть ли решение для JavaScript?

ответ

38

Согласно RFC 2397, нет, нет.

Также не существует attribute элемента <a>, который вы также можете использовать.

Однако HTML5 впоследствии ввел атрибут на <a> элемента download, хотя в то время написания поддержки не является универсальной (нет поддержки MSIE, например)

12

Номер

Вся цель не является что это поток данных, а не файл. Источник данных не должен знать, что пользовательский агент обрабатывает его как файл ... и это не так.

+5

Цель данных: `заключается в том, чтобы вымыть блок из внутренних данных в формат URL без необходимости _read_ из источника на основе протокола. Ссылка в ответе @ silex показывает, что возможность предлагать предпочтительное имя _write_ it to считается полезной, даже если она еще не реализована. – Alnitak 2011-06-05 09:27:55

+1

@ Алнитак: Полезно? Абсолютно. Технически целесообразно? Все еще не убежден. :) – 2011-06-05 20:21:17

+3

@Tomalak рассматривает разницу между загрузкой данных и их сохранением - только потому, что blob закодирован inline в данных: URL-адрес не означает, что у него не должно быть предпочтительного имени для его сохранения. – Alnitak 2011-06-05 20:26:40

3

Это своего рода хакерство, но я был в той же ситуации раньше. Я динамически генерировал текстовый файл в javascript и хотел предоставить его для загрузки, закодировав его с помощью URI данных.

Это возможно с minor Основное вмешательство пользователя. Создайте ссылку <a href="data:...">right-click me and select "Save Link As..." and save as "example.txt"</a>. Как я уже сказал, это неэлегантно, но оно работает, если вам не нужно профессиональное решение.

Это можно сделать менее болезненным, используя flash, чтобы скопировать имя в буфер обмена в первую очередь. Конечно, если вы позволите себе использовать Flash или Java (теперь, по-моему, с меньшей поддержкой браузера?), Вы, вероятно, можете найти другой способ сделать это.

+0

Это не решение и не соответствует тому, что было предложено. Сожалею. – jcolebrand 2011-06-05 21:38:31

+6

Lol @ «незначительное вмешательство пользователя». Предоставление пользователю возможности сделать все это для вас - это не «незначительное вмешательство пользователя». – 2011-06-06 20:28:29

5

Посмотрите на эту ссылку: http://lists.w3.org/Archives/Public/uri/2010Feb/0069.html

Цитата:

Он даже работает (как, не вызывает проблем) с; base64 в конце
как это (в Opera по крайней мере):

данные: текст/обычный; кодировка = UTF-8; заголовки = Content-Disposition% 3A% 20attachment% 3B% 20filename% 3D% 22with% 20spaces.txt% 22% 0D% 0AContent-Язык % 3A% 20en; base64,4oiaDQo% 3D

Также есть информация в остальном сообщениях обсуждения.

+0

к сожалению это не загружается. – 2011-05-30 02:47:43

+7

Это обсуждение было для расширения _proposed_ в формате URI данных - оно не было реализовано. – Alnitak 2011-05-30 08:14:29

21

Я посмотрел немного в источниках FireFox в NETWERK/протокола/данных/nsDataHandler.cpp

обработчик

данных только разбирает содержание/тип и кодировку, и выглядит, если есть «; base64» в строке

rfc не указывает имя файла и, по крайней мере, firefox не обрабатывает имя файла, код генерирует случайное имя плюс ".часть»

Я также проверил светлячок войти

[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 

интересных файлов, если вы хотите взглянуть на источниках: MOZILLA

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, это w Орки также на светлячок 20 http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#attr-hyperlink-download

+2

Прохладный! Хотя я не обязательно согласен с тем, что Firefox является высшим авторитетом в отношении того, что существует. :) – Gleno 2011-06-05 10:30:55

130

Используйте download атрибут:

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

Живой пример на html5-demos.appspot.com/....

Currently works on Chrome, Firefox, Edge, Opera, но не Safari 10 или IE11.

+0

Этот ответ является единственным полным. Нет, вы не можете сделать это с данными: URI. Да, вы можете указать имя файла для ссылки для загрузки с чистым Javascript. Благодаря! – Biovisualize 2011-11-17 16:03:21

+3

@BioDesign: Он работает даже с данными: URI в хроме. См. Http://jsfiddle.net/pYpqW/ – Senseful 2012-01-17 05:36:32

4

Существует крошечный обходной скрипт на Google Code, который работал для меня:

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

Он добавляет форму с данными в нем, представляет его, а затем снова удаляет форму. Хакки, но это сработало для меня. Требуется jQuery.

Этот поток появился в Google до страницы Google Code, и я подумал, что было бы полезно иметь здесь ссылку.

+0

Интересный скрипт, но он требует, чтобы сервер получал ответ и отправлял его обратно? http://jsfiddle.net/hZySf/ – 2012-01-13 02:03:11

+0

Похож на это. Как я писал, hacky workaround .. – 2012-01-13 21:48:04

8

вы можете добавить атрибут загрузки к элементу привязки.

образец:

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

Следующая Javascript фрагмент кода работает в 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") 
54

Chrome делает это очень простой в эти дни:

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

Вот версия JQuery на основе офф версии Holf и работает с 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(); 
36

HTML только: использовать download атрибут:

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


Javascript только: вы можете сохранить любые данные 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, и края 13+ будет использовать указанное имя файла.

IE11, Пограничные 12 и Safari 9 (который don't support the download attribute) загрузит файл с их именем по умолчанию или они просто показать его в новой вкладке, если это неподдерживаемый тип файла: изображения, видео , звуковые файлы, ...


Если нужна лучшая совместимость Теперь используйте основе флэш-Downloadify в качестве запасного варианта.

3

Используя service workers, это, наконец, возможно в прямом смысле.

  1. Создайте поддельный URL-адрес. Например /saveAs/myPrettyName.jpg
  2. Использовать URL-адрес в <a href, <img src, 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); 
    } 
}); 
0
var isIE = /*@[email protected]*/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() { }); 
    } 
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. Trick должен использовать Файл вместо Blob.

ссылка: https://developer.mozilla.org/de/docs/Web/API/File

-1

Ответ прост, что даже большинство людей не ожидали.

Мы можем просто добавить косую черту после загрузки ссылки и поместить нужное имя после этой косой черты.

Например:

<a href"http://foo.goo/xxoo.mp4/nice.mp4"></a>

Диалог загрузки будет выскочить с именем файла по умолчанию nice.mp4 вместо xxoo.mp4

Данные: URI следуют за то же правило

-1

Вы действительно можете добиться этого, в Chrome и FireFox.

Попробуйте следующий URL-адрес, он будет загружен код, который использовался.

data:text/html;base64,PGEgaHJlZj0iZGF0YTp0ZXh0L2h0bWw7YmFzZTY0LFBHRWdhSEpsWmowaVVGVlVYMFJCVkVGZlZWSkpYMGhGVWtVaUlHUnZkMjVzYjJGa1BTSjBaWE4wTG1oMGJXd2lQZ284YzJOeWFYQjBQZ3BrYjJOMWJXVnVkQzV4ZFdWeWVWTmxiR1ZqZEc5eUtDZGhKeWt1WTJ4cFkyc29LVHNLUEM5elkzSnBjSFErIiBkb3dubG9hZD0idGVzdC5odG1sIj4KPHNjcmlwdD4KZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYScpLmNsaWNrKCk7Cjwvc2NyaXB0Pg==