webentwicklung-frage-antwort-db.com.de

So laden Sie Dateien mit Axios herunter

Ich verwende Axios für grundlegende http-Anforderungen wie "get" und "post" und es funktioniert gut. Jetzt muss ich auch Excel-Dateien herunterladen können. Ist das mit Axios möglich? Wenn ja, hat jemand einen Beispielcode? Wenn nicht, was kann ich sonst in einer Reaktionsanwendung verwenden, um dasselbe zu tun?

19
David Choi

Wenn die Antwort mit einer herunterladbaren Datei geliefert wird, haben die Antwortheader so etwas wie

Content-Disposition: "attachment;filename=report.xls"
Content-Type: "application/octet-stream" // or Content-type: "application/vnd.ms-Excel"

Sie können eine separate Komponente erstellen, die einen versteckten Iframe enthält. 

  import * as React from 'react';

  var MyIframe = React.createClass({

     render: function() {
         return (
           <div style={{display: 'none'}}>
               <iframe src={this.props.iframeSrc} />
           </div>
         );
     }
  });

Jetzt können Sie die URL der herunterladbaren Datei als Requisite an diese Komponente übergeben. Wenn diese Komponente dann Requisite erhält, wird sie erneut gerendert und die Datei wird heruntergeladen. 

Edit: Sie können auch js-file-download module verwenden. Link zu Github Repo

const FileDownload = require('js-file-download');

Axios.get(`http://localhost/downloadFile`)
   .then((response) => {
        FileDownload(response.data, 'report.csv');
   });

Hoffe das hilft :)

35
Hardik Modha

Herunterladen von Dateien (mit Axios und Sicherheit)

Dies ist sogar noch komplexer, wenn Sie Dateien mit Axios herunterladen möchten und einige Sicherheitsmaßnahmen treffen. Um zu verhindern, dass jemand anderes zu viel Zeit darauf verwendet, dies herauszufinden, lassen Sie mich das durchgehen.

Sie müssen 3 Dinge tun:

1. Configure your server to permit the browser to see required HTTP headers
2. Implement the server-side service, and making it advertise the correct file type for the downloaded file.
3. Implementing an Axios handler to trigger a FileDownload dialog within the browser

Diese Schritte sind meistens machbar - werden jedoch durch die Beziehung des Browsers zu CORS erheblich erschwert. Ein Schritt auf einmal:

1. Konfigurieren Sie Ihren (HTTP) Server

Bei der Verwendung von Transportsicherheit kann JavaScript, das in einem Browser ausgeführt wird, [per Design] nur auf 6 der HTTP-Header zugreifen, die tatsächlich vom HTTP-Server gesendet werden. Wenn der Server einen Dateinamen für den Download vorschlagen soll, müssen wir den Browser darüber informieren, dass es "OK" ist, damit JavaScript Zugriff auf andere Header erhält, in denen der vorgeschlagene Dateiname transportiert werden würde.

Nehmen wir zur Diskussion an, dass der Server den vorgeschlagenen Dateinamen innerhalb eines HTTP-Headers namens X-Suggested-Filename übertragen soll. Der HTTP-Server teilt dem Browser mit, dass es OK ist, diesen empfangenen benutzerdefinierten Header für JavaScript/Axios mit dem folgenden Header bereitzustellen:

Access-Control-Expose-Headers: X-Suggested-Filename

Die genaue Methode zum Konfigurieren des HTTP-Servers zum Setzen dieses Headers ist von Produkt zu Produkt unterschiedlich. 

Unter https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers finden Sie eine vollständige Erklärung und eine detaillierte Beschreibung dieser Standard-Header. 

2. Implementieren Sie den serverseitigen Dienst

Ihre serverseitige Service-Implementierung muss nun zwei Dinge ausführen:

1. Create the (binary) document and assign correct ContentType to the response
2. Assign the custom header (X-Suggested-Filename) containing the suggested file name for the client

Dies erfolgt je nach gewähltem Technologie-Stack auf unterschiedliche Weise. Ich werde ein Beispiel mit dem JavaEE 7-Standard skizzieren, der einen Excel-Bericht ausgeben soll:

@GET
@Path("/report/Excel")
@Produces("application/vnd.ms-Excel")
public Response getAllergyAndPreferencesReport() {

    // Create the document which should be downloaded
    final byte[] theDocumentData = .... 

    // Define a suggested filename
    final String filename = ... 

    // Create the JAXRS response
    // Don't forget to include the filename in 2 HTTP headers: 
    //
    // a) The standard 'Content-Disposition' one, and
    // b) The custom 'X-Suggested-Filename'  
    //
    final Response.ResponseBuilder builder = Response.ok(
            theDocumentData, "application/vnd.ms-Excel")
            .header("X-Suggested-Filename", fileName);
    builder.header("Content-Disposition", "attachment; filename=" + fileName);

    // All Done.
    return builder.build();
}

Der Dienst gibt nun das binäre Dokument aus (in diesem Fall einen Excel-Bericht), legt den richtigen Inhaltstyp fest und sendet außerdem einen benutzerdefinierten HTTP-Header mit dem vorgeschlagenen Dateinamen, der beim Speichern des Dokuments verwendet werden soll.

3. Implementieren Sie einen Axios-Handler für das empfangene Dokument

Hier gibt es einige Fallstricke, also stellen wir sicher, dass alle Details korrekt konfiguriert sind:

  1. Der Dienst antwortet auf @GET (d. H. HTTP GET), daher muss der Axios-Aufruf 'axios.get (...)' sein.
  2. Das Dokument wird als Bytestrom übertragen, daher müssen Sie Axios anweisen, die Antwort als HTML5-Blob zu behandeln. (D.h. responseType: 'blob').
  3. In diesem Fall wird die JavaScript-Bibliothek des Datei-Savers verwendet, um den Browser-Dialog zu öffnen. Sie können jedoch einen anderen auswählen. 

Die Skelett-Implementierung von Axios würde dann etwa so aussehen:

 // Fetch the dynamically generated Excel document from the server.
 axios.get(resource, {responseType: 'blob'}).then((response) => {

    // Log somewhat to show that the browser actually exposes the custom HTTP header
    const fileNameHeader = "x-suggested-filename";
    const suggestedFileName = response.headers[fileNameHeader];'
    const effectiveFileName = (suggestedFileName === undefined
                ? "allergierOchPreferenser.xls"
                : suggestedFileName);
    console.log("Received header [" + fileNameHeader + "]: " + suggestedFileName
                + ", effective fileName: " + effectiveFileName);

    // Let the user save the file.
    FileSaver.saveAs(response.data, effectiveFileName);

    }).catch((response) => {
        console.error("Could not Download the Excel report from the backend.", response);
    });
26

Eine allgemeinere Lösung

axios({
  url: 'http://api.dev/file-download', //your url
  method: 'GET',
  responseType: 'blob', // important
}).then((response) => {
   const url = window.URL.createObjectURL(new Blob([response.data]));
   const link = document.createElement('a');
   link.href = url;
   link.setAttribute('download', 'file.pdf'); //or any other extension
   document.body.appendChild(link);
   link.click();
});

Überprüfen Sie die Macken unter https://Gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743

Vollständige Credits an: https://Gist.github.com/javilobo8

8
Viney

Es ist sehr einfach, Javascript-Code, um einen Download für den Benutzer auszulösen:

window.open("<insert URL here>")

Sie wollen/brauchen keine Achsen für diese Operation; Es ist Standard, nur den Browser das tun zu lassen.

Hinweis: Wenn Sie eine Autorisierung für den Download benötigen, funktioniert dies möglicherweise nicht. Ich bin mir ziemlich sicher, dass Sie Cookies verwenden können, um eine solche Anfrage zu autorisieren, vorausgesetzt, sie befindet sich in derselben Domain. In einem solchen Fall funktioniert dies jedoch möglicherweise nicht sofort.


Wie, ob es möglich ist ... nicht mit dem eingebauten Mechanismus zum Herunterladen von Dateien, nein .

1
Multihunter

Axios.post-Lösung mit IE und anderen Browsern

Habe hier einige unglaubliche Lösungen gefunden. Aber sie berücksichtigen häufig keine Probleme mit dem IE Browser. Vielleicht spart es jemand anderem Zeit.

 axios.post("/yourUrl"
                , data,
                {responseType: 'blob'}
            ).then(function (response) {
                    let fileName = response.headers["content-disposition"].split("filename=")[1];
                    if (window.navigator && window.navigator.msSaveOrOpenBlob) { // IE variant
                        window.navigator.msSaveOrOpenBlob(new Blob([response.data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}),
                            fileName);
                    } else {
                        const url = window.URL.createObjectURL(new Blob([response.data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}));
                        const link = document.createElement('a');
                        link.href = url;
                        link.setAttribute('download', response.headers["content-disposition"].split("filename=")[1]);
                        document.body.appendChild(link);
                        link.click();
                    }
                }
            );

beispiel oben für Excel-Dateien, aber mit kleinen Änderungen kann auf jedes Format angewendet werden.

Und auf dem Server habe ich dies getan, um Excel zu senden

response.contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=exceptions.xlsx")
0
Alex
        axios.get(
            '/app/export'
        ).then(response => {    
            const url = window.URL.createObjectURL(new Blob([response]));
            const link = document.createElement('a');
            link.href = url;
            const fileName = `${+ new Date()}.csv`// whatever your file name .
            link.setAttribute('download', fileName);
            document.body.appendChild(link);
            link.click();
            link.remove();// you need to remove that elelment which is created before.
})
0
Nitin Tyagi

Der Trick besteht darin, ein unsichtbares Ankertag in render() zu erstellen und eine React ref hinzuzufügen, die einen Klick auslöst, sobald die Antwort axios vorliegt:

class Example extends Component {
    state = {
        ref: React.createRef()
    }

    exportCSV = () => {
        axios.get(
            '/app/export'
        ).then(response => {
            let blob = new Blob([response.data], {type: 'application/octet-stream'})
            let ref = this.state.ref
            ref.current.href = URL.createObjectURL(blob)
            ref.current.download = 'data.csv'
            ref.current.click()
        })
    }

    render(){
        return(
            <div>
                <a style={{display: 'none'}} href='empty' ref={this.state.ref}>ref</a>
                <button onClick={this.exportCSV}>Export CSV</button>
            </div>
        )
    }
}

Hier ist die Dokumentation: https://reactjs.org/docs/refs-and-the-dom.html . Eine ähnliche Idee finden Sie hier: https://thewebtier.com/snippets/download-files-with-axios/ .

0
enjolrasyn

Die Funktion zum Ausführen des API-Aufrufs mit axios:

  function getFileToDownload (apiUrl) {
     return axios.get(apiUrl, {
       responseType: 'arraybuffer',
       headers: {
         'Content-Type': 'application/json'
       }
     })
  }

Rufen Sie die Funktion auf und laden Sie die Excel-Datei herunter, die Sie erhalten:

getFileToDownload('putApiUrlHere')
  .then (response => {
      const type = response.headers['content-type']
      const blob = new Blob([response.data], { type: type, encoding: 'UTF-8' })
      const link = document.createElement('a')
      link.href = window.URL.createObjectURL(blob)
      link.download = 'file.xlsx'
      link.click()
  })
0
roli roli