Chcę zapisać dane do istniejącego pliku za pomocą JavaScript. Nie chcę drukować tego na konsoli. Chcę faktycznie zapisywać dane do abc.txt
. Czytałem wiele odpowiedzi na pytania, ale wszędzie tam, gdzie drukują na konsoli. w którymś miejscu podali kod, ale nie działa. Więc proszę, czy ktoś może mi pomóc Jak właściwie zapisywać dane do pliku.
Odniosłem się do kodu, ale nie działa: podaje błąd:
Uncaught TypeError: Illegal constructor
na chrome i
SecurityError: Operacja jest niezabezpieczona.
w Mozilli
var f = "sometextfile.txt";
writeTextFile(f, "Spoon")
writeTextFile(f, "Cheese monkey")
writeTextFile(f, "Onion")
function writeTextFile(afilename, output)
{
var txtFile =new File(afilename);
txtFile.writeln(output);
txtFile.close();
}
Czy możemy więc zapisywać dane do pliku, używając tylko JavaScript, czy NIE?
javascript
html
pareshm
źródło
źródło
Odpowiedzi:
Kilka sugestii na ten temat -
źródło
Możesz tworzyć pliki w przeglądarce za pomocą
Blob
iURL.createObjectURL
. Obsługują to wszystkie najnowsze przeglądarki .Nie możesz bezpośrednio zapisać utworzonego pliku, ponieważ spowodowałoby to ogromne problemy z bezpieczeństwem, ale możesz udostępnić go jako łącze do pobrania dla użytkownika. W przeglądarkach obsługujących atrybut pobierania możesz zasugerować nazwę pliku za pomocą
download
atrybutu łącza. Podobnie jak w przypadku każdego innego pobierania, użytkownik pobierający plik będzie miał ostatnie słowo w sprawie nazwy pliku.var textFile = null, makeTextFile = function (text) { var data = new Blob([text], {type: 'text/plain'}); // If we are replacing a previously generated file we need to // manually revoke the object URL to avoid memory leaks. if (textFile !== null) { window.URL.revokeObjectURL(textFile); } textFile = window.URL.createObjectURL(data); // returns a URL you can use as a href return textFile; };
Oto przykład, w którym zastosowano tę technikę, aby zapisać dowolny tekst z pliku
textarea
.Jeśli chcesz natychmiast rozpocząć pobieranie zamiast wymagać od użytkownika kliknięcia łącza, możesz użyć zdarzeń myszy, aby zasymulować kliknięcie linku myszą, tak jak zrobiła to odpowiedź Lifecube . Stworzyłem zaktualizowany przykład wykorzystujący tę technikę.
var create = document.getElementById('create'), textbox = document.getElementById('textbox'); create.addEventListener('click', function () { var link = document.createElement('a'); link.setAttribute('download', 'info.txt'); link.href = makeTextFile(textbox.value); document.body.appendChild(link); // wait for the link to be added to the document window.requestAnimationFrame(function () { var event = new MouseEvent('click'); link.dispatchEvent(event); document.body.removeChild(link); }); }, false);
źródło
URL
). Ustawienie nazwy pliku nie zadziała w Safari, ponieważ nadal nie ma zaimplementowanegodownload
atrybutu .\n
do reprezentowania nowych linii, tak jak robią to programy UNIX. Prawdopodobnie przeglądasz go w programie Windows, takim jak Notatnik, który nie renderuje\n
znaku jako nowej linii . Jeśli chcesz newlines być poprawnie renderowane w Notatniku i niektórych innych programów Windows, przed oddaniem tekstu doBlob
zastąpienia każdego\n
z\r\n
:text = text.replace(/\n/g, '\r\n')
.mouseover
przez łącze, ale w zależności od tego, ile przetwarza, może to nie działać dobrze.Jeśli mówisz o javascript w przeglądarce, ze względów bezpieczeństwa nie możesz zapisywać danych bezpośrednio do pliku lokalnego. Nowy interfejs API HTML 5 umożliwia tylko odczytywanie plików.
Ale jeśli chcesz zapisać dane i umożliwić użytkownikowi pobieranie jako plik do lokalnego. następujący kod działa:
function download(strData, strFileName, strMimeType) { var D = document, A = arguments, a = D.createElement("a"), d = A[0], n = A[1], t = A[2] || "text/plain"; //build download link: a.href = "data:" + strMimeType + "charset=utf-8," + escape(strData); if (window.MSBlobBuilder) { // IE10 var bb = new MSBlobBuilder(); bb.append(strData); return navigator.msSaveBlob(bb, strFileName); } /* end if(window.MSBlobBuilder) */ if ('download' in a) { //FF20, CH19 a.setAttribute("download", n); a.innerHTML = "downloading..."; D.body.appendChild(a); setTimeout(function() { var e = D.createEvent("MouseEvents"); e.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); a.dispatchEvent(e); D.body.removeChild(a); }, 66); return true; }; /* end if('download' in a) */ //do iframe dataURL download: (older W3) var f = D.createElement("iframe"); D.body.appendChild(f); f.src = "data:" + (A[2] ? A[2] : "application/octet-stream") + (window.btoa ? ";base64" : "") + "," + (window.btoa ? window.btoa : escape)(strData); setTimeout(function() { D.body.removeChild(f); }, 333); return true; }
używać go:
download('the content of the file', 'filename.txt', 'text/plain');
źródło
Powyższa odpowiedź jest przydatna, ale znalazłem kod, który pomaga pobrać plik tekstowy bezpośrednio po kliknięciu przycisku. W tym kodzie możesz również zmienić,
filename
jak chcesz. To czysta funkcja javascript z HTML5. Pracuje dla mnie!function saveTextAsFile() { var textToWrite = document.getElementById("inputTextToSave").value; var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'}); var fileNameToSaveAs = document.getElementById("inputFileNameToSaveAs").value; var downloadLink = document.createElement("a"); downloadLink.download = fileNameToSaveAs; downloadLink.innerHTML = "Download File"; if (window.webkitURL != null) { // Chrome allows the link to be clicked // without actually adding it to the DOM. downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob); } else { // Firefox requires the link to be added to the DOM // before it can be clicked. downloadLink.href = window.URL.createObjectURL(textFileAsBlob); downloadLink.onclick = destroyClickedElement; downloadLink.style.display = "none"; document.body.appendChild(downloadLink); } downloadLink.click(); }
źródło
createObjectURL
. W przeciwieństwie do większości rzeczy w JS, obiekty, które za jej pomocą tworzysz, nie są automatycznie usuwane jako śmieci, gdy nie ma już do nich odniesień; są one zbierane tylko po zamknięciu strony. PonieważURL.revokeObjectURL()
w tym kodzie nie używasz do zwolnienia pamięci używanej przez ostatnie wywołanie, masz wyciek pamięci; jeśli użytkownik dzwonisaveTextFile
wiele razy, będą nadal zużywać coraz więcej pamięci, ponieważ nigdy jej nie zwolniłeś.Próbować
let a = document.createElement('a'); a.href = "data:application/octet-stream,"+encodeURIComponent("My DATA"); a.download = 'abc.txt'; a.click();
Jeśli chcesz pobrać dane binarne, zajrzyj tutaj
Aktualizacja
2020.06.14 Uaktualniam Chrome do 83.0 i nowszych SO snippet stop działa (powód: ograniczenia bezpieczeństwa piaskownicy ) - ale wersja JSFiddle działa - tutaj
źródło
W przypadku braku możliwości skorzystania z nowego
Blob
rozwiązania, czyli z pewnością najlepszego rozwiązania w nowoczesnej przeglądarce, nadal można skorzystać z prostszego podejścia, które przy okazji ma ograniczenie rozmiaru pliku:function download() { var fileContents=JSON.stringify(jsonObject, null, 2); var fileName= "data.json"; var pp = document.createElement('a'); pp.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(fileContents)); pp.setAttribute('download', fileName); pp.click(); } setTimeout(function() {download()}, 500);
$('#download').on("click", function() { function download() { var jsonObject = { "name": "John", "age": 31, "city": "New York" }; var fileContents = JSON.stringify(jsonObject, null, 2); var fileName = "data.json"; var pp = document.createElement('a'); pp.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(fileContents)); pp.setAttribute('download', fileName); pp.click(); } setTimeout(function() { download() }, 500); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button id="download">Download me</button>
źródło
Użyj kodu użytkownika @ useless-code powyżej ( https://stackoverflow.com/a/21016088/327386 ), aby wygenerować plik. Jeśli chcesz pobrać plik automatycznie, przekaż
textFile
właśnie wygenerowany plik do tej funkcji:var downloadFile = function downloadURL(url) { var hiddenIFrameID = 'hiddenDownloader', iframe = document.getElementById(hiddenIFrameID); if (iframe === null) { iframe = document.createElement('iframe'); iframe.id = hiddenIFrameID; iframe.style.display = 'none'; document.body.appendChild(iframe); } iframe.src = url; }
źródło
Znalazłem tutaj dobre odpowiedzi, ale znalazłem też prostszy sposób.
Przycisk do tworzenia obiektu blob i łącze pobierania można połączyć w jeden link, ponieważ element link może mieć atrybut onclick. (Odwrotna sytuacja wydaje się niemożliwa, dodawanie href do przycisku nie działa.)
Możesz stylizować link jako przycisk za pomocą
bootstrap
, który nadal jest czystym javascriptem, z wyjątkiem stylizacji.Połączenie przycisku i linku pobierania również ogranicza kod, ponieważ potrzeba mniej tych brzydkich
getElementById
wywołań.W tym przykładzie wystarczy jedno kliknięcie przycisku, aby utworzyć tekstowy obiekt blob i pobrać go:
<a id="a_btn_writetofile" download="info.txt" href="#" class="btn btn-primary" onclick="exportFile('This is some dummy data.\nAnd some more dummy data.\n', 'a_btn_writetofile')" > Write To File </a> <script> // URL pointing to the Blob with the file contents var objUrl = null; // create the blob with file content, and attach the URL to the downloadlink; // NB: link must have the download attribute // this method can go to your library function exportFile(fileContent, downloadLinkId) { // revoke the old object URL to avoid memory leaks. if (objUrl !== null) { window.URL.revokeObjectURL(objUrl); } // create the object that contains the file data and that can be referred to with a URL var data = new Blob([fileContent], { type: 'text/plain' }); objUrl = window.URL.createObjectURL(data); // attach the object to the download link (styled as button) var downloadLinkButton = document.getElementById(downloadLinkId); downloadLinkButton.href = objUrl; }; </script>
źródło
const data = {name: 'Ronn', age: 27}; //sample json const a = document.createElement('a'); const blob = new Blob([JSON.stringify(data)]); a.href = URL.createObjectURL(blob); a.download = 'sample-profile'; //filename to download a.click();
Sprawdź dokumentację obiektu Blob tutaj - Blob MDN, aby zapewnić dodatkowe parametry dla typu pliku. Domyślnie utworzy plik .txt
źródło
Tak, to możliwe. Oto kod
const fs = require('fs') let data = "Learning how to write in a file." fs.writeFile('Output.txt', data, (err) => { // In case of a error throw err. if (err) throw err; })
źródło