Stáhněte si soubor pomocí jQuery.Ajax

Mám akci Struts2 na straně serveru pro stahování souborů.

<action name="download" class="com.xxx.DownAction">
    <result name="success" type="stream">
        <param name="contentType">text/plain</param>
        <param name="inputName">imageStream</param>
        <param name="contentDisposition">attachment;filename={fileName}</param>
        <param name="bufferSize">1024</param>
    </result>
</action>

Když však zavolám akci pomocí jQuery:

$.post(
  "/download.action",{
    para1:value1,
    para2:value2
    ....
  },function(data){
      console.info(data);
   }
);

ve Firebugu vidím, že se data načítají pomocí Binárního streamu . Zajímalo by mě, jak otevřít okno stahování souboru pomocí kterého může uživatel uložit soubor lokálně?

Odpověď

Aktualizace moderních prohlížečů pro rok 2019

Toto je přístup, který bych nyní doporučil s několika upozorněními:

  • Je vyžadován relativně moderní prohlížeč
  • Pokud se očekává, že soubor bude velmi velký pravděpodobně byste měli udělat něco podobného původnímu přístupu (iframe a cookie), protože některé z níže uvedených operací by pravděpodobně mohly spotřebovat systémovou paměť přinejmenším tak velkou jako stahovaný soubor a/nebo jiné zajímavé vedlejší efekty CPU.

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(resp => resp.blob())
  .then(blob => {
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.style.display = 'none';
    a.href = url;
    // the filename you want
    a.download = 'todo-1.json';
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
    alert('your file has downloaded!'); // or you know, something with better UX...
  })
  .catch(() => alert('oh no!'));

Původní přístup založený na jQuery/iframe/cookie z roku 2012

Blueish má v tomto naprostou pravdu, nemůžete to udělat přes Ajax, protože JavaScript nemůže ukládat soubory přímo do počítače uživatele (z bezpečnostních důvodů). Bohužel ukazuje hlavní okno Adresa URL při stahování souboru znamená, že máte malou kontrolu nad tím, jaká je uživatelská zkušenost, když dojde ke stažení souboru.

Vytvořil jsem jQuery File Download, který umožňuje „Ajax like“ zážitek se stahováním souborů doplněným zpětnými voláními OnSuccess a OnFailure, aby bylo zajištěno lepší uživatelské prostředí. Podívejte se na můj blogový příspěvek o běžném problému, který plugin řeší, a některých způsobech jeho použití a také ukázku jQuery File Download v akci. Zde je zdroj

Zde je ukázka jednoduchého případu použití pomocí zdroje pluginu se sliby. Ukázková stránka obsahuje také mnoho dalších „lepších UX“ příkladů.

$.fileDownload('some/file.pdf')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });

V závislosti na tom, jaké prohlížeče potřebujete podporovat, možná budete moci použít https://github.com/eligrey/FileSaver.js/, který umožňuje explicitnější kontrolu než metoda IFRAME, kterou používá jQuery File Download.