Gibt es eine Möglichkeit, eine Textdatei auf der Client-Seite zu erstellen und den Benutzer aufzufordern, sie herunterzuladen, ohne dass eine Interaktion mit dem Server erforderlich ist? Ich weiß, dass ich nicht direkt auf den Rechner des Nutzers schreiben kann (Sicherheit und so), aber kann ich eine Datei erstellen und ihn auffordern, sie zu speichern?
Antworten
Zu viele Anzeigen?Utilice Blob :
function download(content, mimeType, filename){
const a = document.createElement('a') // Create "a" element
const blob = new Blob([content], {type: mimeType}) // Create a blob (file-like object)
const url = URL.createObjectURL(blob) // Create an object URL from blob
a.setAttribute('href', url) // Set "a" element link
a.setAttribute('download', filename) // Set download filename
a.click() // Start downloading
}
Blob wird von allen modernen Browsern unterstützt.
Caniuse-Unterstützungstabelle für Blob:
Und hier MDN-Dokumente
Die folgende Methode funktioniert in IE11+, Firefox 25+ und Chrome 30+:
<a id="export" class="myButton" download="" href="#">export</a>
<script>
function createDownloadLink(anchorSelector, str, fileName){
if(window.navigator.msSaveOrOpenBlob) {
var fileData = [str];
blobObject = new Blob(fileData);
$(anchorSelector).click(function(){
window.navigator.msSaveOrOpenBlob(blobObject, fileName);
});
} else {
var url = "data:text/plain;charset=utf-8," + encodeURIComponent(str);
$(anchorSelector).attr("download", fileName);
$(anchorSelector).attr("href", url);
}
}
$(function () {
var str = "hi,file";
createDownloadLink("#export",str,"file.txt");
});
</script>
Dies in Aktion sehen: http://jsfiddle.net/Kg7eA/
Firefox und Chrome unterstützen Daten-URI für die Navigation, was uns ermöglicht, Dateien zu erstellen, indem wir zu einem Daten-URI navigieren, während der IE dies aus Sicherheitsgründen nicht unterstützt.
Andererseits verfügt der IE über eine API zum Speichern eines Blob, der zum Erstellen und Herunterladen von Dateien verwendet werden kann.
Wir können die URL api, insbesondere URL.createObjectURL() und die Blob api zum Kodieren und Herunterladen von so ziemlich allem.
Wenn Ihr Download klein ist, funktioniert das gut:
document.body.innerHTML +=
`<a id="download" download="PATTERN.json" href="${URL.createObjectURL(new Blob([JSON.stringify("HELLO WORLD", null, 2)]))}"> Click me</a>`
download.click()
download.outerHTML = ""
Wenn Ihr Download sehr umfangreich ist, ist es besser, ein Link-Element mit den Download-Parametern zu erstellen und einen Klick auszulösen, anstatt das DOM zu verwenden.
Beachten Sie, dass das Link-Element nicht an das Dokument angehängt ist, aber der Klick funktioniert trotzdem! Auf diese Weise ist es möglich, einen Download von vielen hundert Mo zu erstellen, da das DOM nicht verändert wird (andernfalls kann die riesige URL im DOM eine Quelle für das Einfrieren von Tabs sein).
const stack = {
some: "stuffs",
alot: "of them!"
}
BUTTONDOWNLOAD.onclick = (function(){
let j = document.createElement("a")
j.download = "stack_"+Date.now()+".json"
j.href = URL.createObjectURL(new Blob([JSON.stringify(stack, null, 2)]))
j.click()
})
<button id="BUTTONDOWNLOAD">DOWNLOAD!</button>
Bonus! Download beliebig zyklische Objekte vermeiden Sie die Fehler:
TypeError: zyklischer Objektwert (Firefox) TypeError: Konvertierung
circular structure to JSON (Chrome und Opera) TypeError: Kreisförmig
Referenz im Wertargument nicht unterstützt (Edge)
Verwendung von https://github.com/douglascrockford/JSON-js/blob/master/cycle.js
In diesem Beispiel wird das Herunterladen der document
Objekt als json.
/* JSON.decycle */
if(typeof JSON.decycle!=="function"){JSON.decycle=function decycle(object,replacer){"use strict";var objects=new WeakMap();return(function derez(value,path){var old_path;var nu;if(replacer!==undefined){value=replacer(value)}
if(typeof value==="object"&&value!==null&&!(value instanceof Boolean)&&!(value instanceof Date)&&!(value instanceof Number)&&!(value instanceof RegExp)&&!(value instanceof String)){old_path=objects.get(value);if(old_path!==undefined){return{$ref:old_path}}
objects.set(value,path);if(Array.isArray(value)){nu=[];value.forEach(function(element,i){nu[i]=derez(element,path+"["+i+"]")})}else{nu={};Object.keys(value).forEach(function(name){nu[name]=derez(value[name],path+"["+JSON.stringify(name)+"]")})}
return nu}
return value}(object,"$"))}}
document.body.innerHTML +=
`<a id="download" download="PATTERN.json" href="${URL.createObjectURL(new Blob([JSON.stringify(JSON.decycle(document), null, 2)]))}"></a>`
download.click()
Das Paket js-file-download von github.com/kennethjiang/js-file-download behandelt Randfälle bei der Browserunterstützung:
Quelle anzeigen um zu sehen, wie es die auf dieser Seite erwähnten Techniken anwendet.
Einrichtung
yarn add js-file-download
npm install --save js-file-download
Verwendung
import fileDownload from 'js-file-download'
// fileDownload(data, filename, mime)
// mime is optional
fileDownload(data, 'filename.csv', 'text/csv')
Diese Lösung ist direkt aus dem Github-Repository von tiddlywiki (tiddlywiki.com) entnommen. Ich habe tiddlywiki in fast allen Browsern verwendet und es funktioniert einwandfrei:
function(filename,text){
// Set up the link
var link = document.createElement("a");
link.setAttribute("target","_blank");
if(Blob !== undefined) {
var blob = new Blob([text], {type: "text/plain"});
link.setAttribute("href", URL.createObjectURL(blob));
} else {
link.setAttribute("href","data:text/plain," + encodeURIComponent(text));
}
link.setAttribute("download",filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
Github Repo: Speichermodul herunterladen