2008-11-12 6 views
197

Si par exemple vous suivez le lien:Est-il possible de spécifier un nom de fichier suggéré lors de l'utilisation de données: URI?

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

Le navigateur vous demandera de télécharger un fichier contenant des données détenues en base64 dans le lien lui-même. Est-il possible de suggérer un nom par défaut dans le balisage? Si non, existe-t-il une solution JavaScript?

+0

peut-être sans rapport avec cette question, mais je suggère d'utiliser URL.createObjectURL de & blob si ce n'est pas un serveur ou ancien obstacle navigateur – Endless

+1

Certains navigateurs prennent en charge le paramètre optionnel de mediatype « name »: 'données: application/pdf; name = document.pdf; base64, BASE64_DATA_ENCODED' – mems

+0

J'ai eu le problème avec Firefox pdf.js qui a tendance à se bloquer dans certains cas s'il ne peut extraire un nom de fichier de l'uri de données. voir https://stackoverflow.com/questions/45585921/firefox-hangs-when-displaying-a-pdf-via-data-url/45585922#45585922 – Bernhard

Répondre

38

Selon RFC 2397, non, il n'y en a pas.

Il ne semble pas non plus y avoir attribute de l'élément <a> que vous pouvez utiliser.

Cependant HTML5 a ensuite introduit l'attribut download sur l'élément <a>, bien au moment de l'écriture est un soutien universel ne (pas de support MSIE, par exemple)

+9

la deuxième phrase était juste au moment de l'écriture, mais [isn ' t plus] (http://developers.whatwg.org/links.html#downloading-resources). à partir de maintenant, il n'est pas encore largement mis en œuvre, cependant. –

+0

@flyingsheep intéressant - merci pour le lien! – Alnitak

+0

voir [ce commentaire] (http://stackoverflow.com/questions/283956/is-there-any-way-to-specify-a-suggested-filename-when-using-data-uri/283982#comment12391386_6943481) pour plus d'infos :) –

12

n °

Le but entier est que c'est un flux de données, pas un fichier. La source de données ne devrait avoir aucune connaissance de l'agent utilisateur qui le gère comme un fichier ... et ce n'est pas le cas.

+5

Le but de 'data: 'est de falsifier un bloc de données _internal_ en format URL sans avoir à le lire depuis une source basée sur un protocole. Le lien dans la réponse de @ silex montre que la possibilité de suggérer un nom préféré à _write_ it est considérée comme utile, même si elle n'est pas encore implémentée. – Alnitak

+1

@Alnitak: Utile? Absolument. Techniquement approprié? Toujours pas convaincu. :) –

+3

@Tomalak considère la différence entre charger les données et les sauvegarder - simplement parce qu'un code blob est encodé en ligne dans une donnée: URL ne signifie pas qu'il ne devrait pas avoir de nom préféré pour l'enregistrer. – Alnitak

3

C'est un peu hackish, mais j'ai été dans la même situation avant. Je générais dynamiquement un fichier texte en javascript et je voulais le fournir en téléchargement en l'encodant avec l'URI de données.

Ceci est possible avec mineur intervention majeure de l'utilisateur. Générer un lien <a href="data:...">right-click me and select "Save Link As..." and save as "example.txt"</a>. Comme je l'ai dit, c'est inélégant, mais cela fonctionne si vous n'avez pas besoin d'une solution professionnelle. Cela peut être rendu moins douloureux en utilisant le flash pour copier le nom dans le presse-papiers en premier. Bien sûr, si vous vous permettez d'utiliser Flash ou Java (maintenant avec de moins en moins de support de navigateur je pense?), Vous pourriez probablement trouver une autre façon de le faire.

+0

Ceci n'est pas une solution et ne répond pas à ce qui a été demandé. Pardon. – jcolebrand

+6

Lol @ "intervention mineure de l'utilisateur". Faire en sorte que l'utilisateur fasse tout pour vous n'est pas une "intervention mineure de l'utilisateur". –

+0

Combinez cela avec http://stackoverflow.com/questions/17311645/download-image-with-javascript pour déclencher le lien généré et vous n'avez pas besoin d'intervention de l'utilisateur. Vous pouvez spécifier l'attribut [HTML5 'download'] (http://davidwalsh.name/download-attribute) pour suggérer un nom tel que mentionné par [many] (http://stackoverflow.com/a/6943481/1037948) [ autre] (http://stackoverflow.com/a/16523173/1037948) [réponses] (http://stackoverflow.com/a/21915171/1037948). – drzaus

5

Regardez ce lien: http://lists.w3.org/Archives/Public/uri/2010Feb/0069.html

Quote:

Il fonctionne même (comme dans, ne provoque pas un problème) avec, à la fin base64
comme celui-ci (dans Opera au moins):

données: text/plain; charset = UTF-8; headers = Content-Disposition% 3A% 20attachment% 3B% 20filename% 3D% 22with% 20spaces.txt% 22% 0D% 0AContent-Language % 3A% 20en; base64,4oiaDQo% 3D

De plus, il y a quelques informations dans les autres messages de la discussion.

+0

malheureusement, cela ne se télécharge pas. –

+7

Cette discussion portait sur une extension de _proposed_ au format URI de données - elle n'a pas été implémentée. – Alnitak

+0

Mis en œuvre ou non, avec un support existant pour les paramètres arbitraires ce serait génial. – Dan

21

J'ai regardé un peu dans FireFox sources Netwerk/protocole/data/nsDataHandler.cpp

gestionnaire de données

contenu ne fait qu'analyser/type et charset, et regarde s'il est "; base64" dans la chaîne Les caractéristiques de rfc aucun nom de fichier et au moins firefox ne gère aucun nom de fichier pour cela, le code génère un nom aléatoire plus ".partie »

J'ai aussi vérifié firefox journal

[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 

fichiers intéressants si vous voulez regarder les sources de 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 

Je pense que vous pouvez arrêter de chercher une solution pour l'instant , parce que je soupçonne qu'il n'y en a pas :)

comme remarqué dans ce fil html5 a download attribut, il w orks aussi sur Firefox 20 http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#attr-hyperlink-download

+2

Cool! Bien que je ne suis pas nécessairement d'accord que Firefox est l'autorité ultime sur ce qui existe. :) – Gleno

130

Utilisez l'attribut download:

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

exemple en direct sur html5-demos.appspot.com/....

Currently works on Chrome, Firefox, Edge, Opera, mais pas Safari 10 ou IE11.

+0

Cette réponse est la seule complète. Non, vous ne pouvez pas le faire avec des données: URI. Oui, vous pouvez fournir un nom de fichier à un lien de téléchargement avec Javascript pur. Merci! – Biovisualize

+3

@BioDesign: Cela fonctionne même avec les données: les URI en chrome. Voir: http://jsfiddle.net/pYpqW/ – Senseful

+6

mais vous ne pouvez pas le faire avec 'window.location.replace'. si par exemple vous voulez créer un data: uri ou un généré par ['window.URL.createObjectURL'] (https://developer.mozilla.org/en/Document_Object_Model_%28DOM%29/window.URL.createObjectURL), et le télécharger comme fichier, vous devrez créer un et cliquez dessus: http://jsfiddle.net/flyingsheep/wpQtH/ (non, '$ (...). click()' ne fonctionne pas) –

4

Il y a un script de contournement minuscule sur Google Code qui a fonctionné pour moi:

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

Il ajoute un formulaire avec les données qu'il contient, soumet et supprime ensuite à nouveau le formulaire. Hacky, mais il a fait le travail pour moi. Requiert jQuery.

Ce sujet est apparu dans Google avant la page du code Google et j'ai pensé qu'il pourrait être utile d'avoir le lien ici aussi.

+0

Un script intéressant, mais il faut que le serveur reçoive la réponse et la renvoie correctement? http://jsfiddle.net/hZySf/ –

+0

On dirait ça. Comme je l'ai écrit, hacky contournement .. –

+0

Je ne suis pas sûr d'où le fichier est en cours de création .. est ce fichier stocké dans l'encodage base64? (Je ne suis pas trop familier avec base64) – streetlight

8

Vous pouvez ajouter un attribut de téléchargement à l'élément d'ancrage.

échantillon:

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

Cela fonctionne pour le chrome – diyism

13

ci-dessous extrait de code JavaScript fonctionne dans Chrome en utilisant le nouvel attribut « téléchargement » de liens et de simuler un clic.

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

Et l'exemple suivant son utilisation:

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

Cela ne fonctionne pas dans Firefox, j'ai ajouté une réponse étendue ci-dessous avec la compatibilité Fx. –

54

Chrome en fait très simple ces jours-ci:

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

Idk que toutes ces autres réponses parlent de cela a fonctionné au premier essai dans Chrome 30. –

+1

Il fait maintenant mais ce n'était pas toujours si facile. Beaucoup de ces réponses sont d'il y a des années. Et ils fonctionnent également pour d'autres navigateurs. – Holf

+7

Reportez-vous à [http://caniuse.com/#feat=download](http://caniuse.com/#feat=download) pour une liste complète de la compatibilité du navigateur. – tixastronauta

3

Voici une version jQuery basé sur de la version de Holf et travaille avec Chrome et Firefox alors que sa version semble fonctionner uniquement avec Chrome. C'est un peu étrange d'ajouter quelque chose au corps pour le faire mais si quelqu'un a une meilleure option, je suis tout à fait pour.

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

Avec jQuery 1.11, je reçois une exception à cause du .remove(). J'ai contourné ceci en assignant '$(). AppendTo()' à une variable puis en appelant 'variable.click(); variable.remove() ' –

+0

@ p0lar_bear vous devriez obtenir cette exception avec n'importe quel jQuery, car obtenir le' [0] 'de n'importe quel" élément jQuery "devrait renvoyer le premier élément DOM qu'il représente, qui" sort vraiment de "jQuery . – drzaus

+0

Vous ne devriez pas avoir besoin d'ajouter/supprimer l'élément du tout - voir les commentaires à http://stackoverflow.com/a/17311705/1037948 – drzaus

36

HTML uniquement: utiliser l'download attribut:

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


Javascript seulement: vous pouvez enregistrer une URI de données avec ce code:

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, et Edge 13+ utilisera le nom de fichier spécifié.

IE11, le Edge 12 et Safari 9 (qui don't support the download attribute) va télécharger le fichier avec leur nom par défaut ou ils affichera simplement dans un nouvel onglet, si elle est d'un type de fichier pris en charge: images, vidéos , les fichiers audio, ...


Si besoin d'une meilleure compatibilité maintenant, utilisez la fonction flash Downloadify comme solution de repli.

+1

Cela ne fonctionne pas pour moi (chrome 32) – billy

+0

Les deux démos fonctionnent bien pour moi dans Chrome 38 (mais ils devraient fonctionner dans Chrome 14+) –

+0

* chrome 38 bêta ... de toute façon ... – billy

3

En utilisant service workers, c'est finalement possible dans le vrai sens du terme.

  1. Créez une fausse URL. Par exemple /saveAs/myPrettyName.jpg
  2. Utilisez l'URL dans <a href, <img src, window.open (url), absolument tout ce qui peut être fait avec une "vraie" URL.
  3. À l'intérieur de l'agent, attrapez l'événement d'extraction et répondez avec les données correctes.

Le navigateur proposera maintenant myPrettyName.jpg même si l'utilisateur ouvre le fichier dans un nouvel onglet et essaie de le sauvegarder à cet endroit. Ce sera exactement comme si le fichier venait du serveur.

// 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

Intéressant! La prise en charge semble pour le moment très superficielle: http://caniuse.com/#feat=serviceworkers – tuomassalo

+0

Y a-t-il un moyen de "répondre" avec une autre URL directe à un fichier? –

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() { }); 
    } 
+1

pls ajouter une explication plus détaillée à votre réponse - http://stackoverflow.com/help/how-to-answer –

+0

cette réponse est garbage –

2

Celui-ci fonctionne avec Firefox 43,0 (plus non testé):

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> 

Si le bouton est cliqué, il offre un fichier nommé hello.bin pour le téléchargement. Astuce est d'utiliser Fichier au lieu de Blob.

Référence: https://developer.mozilla.org/de/docs/Web/API/File

-1

La réponse est simple que même la plupart des gens ne m'y attendais pas.

Nous pouvons simplement ajouter une barre oblique après le lien à télécharger et mettre le nom de fichier dont nous avons besoin après cette barre oblique.

Par exemple:

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

La boîte de dialogue de téléchargement sauterait avec un nom de fichier par défaut nice.mp4 au lieu de xxoo.mp4

Les données: URI suivre la même règle

-1

Vous pouvez réellement y parvenir, dans Chrome et FireFox.

Essayez l'URL suivante, il va télécharger le code qui a été utilisé.

data:text/html;base64,PGEgaHJlZj0iZGF0YTp0ZXh0L2h0bWw7YmFzZTY0LFBHRWdhSEpsWmowaVVGVlVYMFJCVkVGZlZWSkpYMGhGVWtVaUlHUnZkMjVzYjJGa1BTSjBaWE4wTG1oMGJXd2lQZ284YzJOeWFYQjBQZ3BrYjJOMWJXVnVkQzV4ZFdWeWVWTmxiR1ZqZEc5eUtDZGhKeWt1WTJ4cFkyc29LVHNLUEM5elkzSnBjSFErIiBkb3dubG9hZD0idGVzdC5odG1sIj4KPHNjcmlwdD4KZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYScpLmNsaWNrKCk7Cjwvc2NyaXB0Pg== 
Questions connexes