Utwórz plik w pamięci do pobrania przez użytkownika, a nie przez serwer

Czy jest jakiś sposób, aby utworzyć plik tekstowy po stronie klienta i poprosić użytkownika, aby go pobrać, bez żadnej interakcji z serwerem? Wiem, że nie mogę pisać bezpośrednio na ich komputerze(Bezpieczeństwo i w ogóle), ale czy mogę utworzyć i poprosić ich o zapisanie?

Author: Joseph Silber, 2010-09-08

16 answers

Możesz użyć Uri danych. Obsługa przeglądarek jest różna; Zobacz Wikipedia . Przykład:

<a href="data:application/octet-stream;charset=utf-16le;base64,//5mAG8AbwAgAGIAYQByAAoA">text file</a>

Strumień oktetu ma wymusić monit o pobranie. W przeciwnym razie prawdopodobnie otworzy się w przeglądarce.

Do CSV możesz użyć:

<a href="data:application/octet-stream,field1%2Cfield2%0Afoo%2Cbar%0Agoo%2Cgai%0A">CSV Octet</a>

Spróbuj jsfiddle demo .

 364
Author: Matthew Flaschen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-08 08:10:02

Proste rozwiązanie dla przeglądarek gotowych do HTML5...

function download(filename, text) {
  var element = document.createElement('a');
  element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
  element.setAttribute('download', filename);

  element.style.display = 'none';
  document.body.appendChild(element);

  element.click();

  document.body.removeChild(element);
}
form * {
  display: block;
  margin: 10px;
}
<form onsubmit="download(this['name'].value, this['text'].value)">
  <input type="text" name="name" value="test.txt">
  <textarea name="text"></textarea>
  <input type="submit" value="Download">
</form>

Użycie

download('test.txt', 'Hello world!');
 553
Author: Matěj Pokorný,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-30 20:08:51

Wszystkie powyższe przykłady działają dobrze w chrome i IE, ale nie w Firefoksie. Rozważ dodanie kotwicy do ciała i usunięcie jej po kliknięciu.

var a = window.document.createElement('a');
a.href = window.URL.createObjectURL(new Blob(['Test,Text'], {type: 'text/csv'}));
a.download = 'test.csv';

// Append anchor to body.
document.body.appendChild(a);
a.click();

// Remove anchor from body
document.body.removeChild(a);
 158
Author: naren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-18 16:11:24

Wszystkie powyższe rozwiązania nie działały we wszystkich przeglądarkach. Oto, co w końcu działa na IE 10+, Firefox i Chrome (i Bez jQuery lub jakiejkolwiek innej biblioteki):

save: function(filename, data) {
    var blob = new Blob([data], {type: 'text/csv'});
    if(window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveBlob(blob, filename);
    }
    else{
        var elem = window.document.createElement('a');
        elem.href = window.URL.createObjectURL(blob);
        elem.download = filename;        
        document.body.appendChild(elem);
        elem.click();        
        document.body.removeChild(elem);
    }
}

Zauważ, że w zależności od twojej sytuacji możesz również zadzwonić do URL .revokeObjectURL po usunięciu elem. Zgodnie z docs dla URL.createObjectURL :

Za każdym razem, gdy wywołujesz createObjectURL (), tworzony jest nowy adres URL obiektu, nawet jeśli utworzyłeś go już dla tego samego obiekt. Każdy z nich musi być zwolniony przez wywołanie URL.revokeObjectURL (), gdy nie są już potrzebne. Przeglądarki zwalniają je automatycznie po rozładowaniu dokumentu; jednak dla optymalnej wydajności i wykorzystania pamięci, jeśli są bezpieczne czasy, kiedy można je wyraźnie rozładować, należy to zrobić.

 146
Author: Ludovic Feltz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-12 15:20:01

Z przyjemnością korzystam FileSaver.js . Jego kompatybilność jest całkiem dobra (IE10+ i wszystko inne) i jest bardzo prosta w użyciu:

var blob = new Blob(["some text"], {
    type: "text/plain;charset=utf-8;",
});
saveAs(blob, "thing.txt");
 102
Author: Daniel Buckmaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-08 23:05:25

Następująca metoda działa w IE11+, Firefox 25 + i 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>

Zobacz to w akcji: http://jsfiddle.net/Kg7eA/

Firefox i Chrome obsługują Dane URI do nawigacji, co pozwala nam tworzyć pliki, przechodząc do danych URI, podczas gdy IE nie obsługuje go ze względów bezpieczeństwa.

Z drugiej strony, IE posiada API do zapisywania obiektów blob, które można wykorzystać do tworzenia i pobierania plików.

 19
Author: dinesh ygv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-27 06:55:52

Rozwiązanie działające na IE10: (Potrzebowałem pliku csv, ale wystarczy zmienić typ i nazwę pliku na txt)

var csvContent=data; //here we load our csv data 
var blob = new Blob([csvContent],{
    type: "text/csv;charset=utf-8;"
});

navigator.msSaveBlob(blob, "filename.csv")
 8
Author: Dzarek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-27 09:10:59

To rozwiązanie jest pobierane bezpośrednio z tiddlywiki (tiddlywiki.com) repozytorium github. Używałem tiddlywiki w prawie wszystkich przeglądarkach i działa jak urok:

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: pobierz Moduł wygaszacza

 8
Author: Danielo515,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-15 18:52:36

Jeśli chcesz przekonwertować ciąg znaków, aby był dostępny do pobrania, możesz spróbować tego za pomocą jQuery.

$('a.download').attr('href', 'data:application/csv;charset=utf-8,' + encodeURI(data));
 8
Author: Rick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-16 16:41:32
var element = document.createElement('a');
element.setAttribute('href', 'data:text/text;charset=utf-8,' +      encodeURI(data));
element.setAttribute('download', "fileName.txt");
element.click();
 5
Author: MANVENDRA LODHI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-09 11:55:37

Od kwietnia 2014 r. API plików mogą nie być standaryzowane w W3C. każdy, kto patrzy na rozwiązanie z blobem, powinien zachować ostrożność.

HTML5 rocks heads up

Lista dyskusyjna W3C na FileSytem API

 4
Author: pravin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-20 15:47:54

Na podstawie odpowiedzi @ Rick, która była bardzo pomocna.

Musisz scape the string data jeśli chcesz podzielić się nim w ten sposób:

$('a.download').attr('href', 'data:application/csv;charset=utf-8,'+ encodeURI(data));

` Sorry I can not comment on @ Rick ' s answer due to my current low reputation in StackOverflow.

An sugestia edycji {[10] } została udostępniona i odrzucona.

 4
Author: atfornes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-07 14:59:01

Jak wspomniano wcześniej, filesaver jest świetnym pakietem do pracy z plikami po stronie klienta. Ale nie jest dobrze z dużymi plikami. StreamSaver.js jest alternatywnym rozwiązaniem (wskazywanym w serwerze plików.js), które mogą obsługiwać duże pliki:

const fileStream = streamSaver.createWriteStream('filename.txt', size);
const writer = fileStream.getWriter();
for(var i = 0; i < 100; i++){
    var uint8array = new TextEncoder("utf-8").encode("Plain Text");
    writer.write(uint8array);
}
writer.close()
 4
Author: مصطفی,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-16 20:42:42

Możesz nawet zrobić coś lepszego niż tylko URI - używając Chrome możesz również zasugerować nazwę pliku, jak wyjaśniono w Ten post na blogu o nazywaniu pobierania przy użyciu Uri .

 3
Author: owencm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-06 21:08:22

Jeśli plik zawiera dane tekstowe, techniką, której używam, jest umieszczenie tekstu w elemencie textarea i wybranie go przez użytkownika (kliknij w textarea, a następnie ctrl-A), a następnie skopiowanie i wklejenie do edytora tekstu.

 -19
Author: HBP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-08 06:51:27

Rzeczywiście jest to możliwe-użyj Flasha.

Możesz albo wygenerować zawartość za pomocą JS, a następnie zainicjować niektóre var flash lub po prostu zrobić wszystko w filmie flash.

Proszę spojrzeć na to , aby uzyskać kilka ważnych uwag.

 -30
Author: Mr.RoyDiibs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-08 06:51:21