vue react nodejs from descargar con archivo reactjs axios

reactjs - react - vue download pdf



Cómo descargar archivos usando axios (6)

Descarga de archivos (usando Axios y Seguridad)

En realidad, esto es aún más complejo cuando desea descargar archivos utilizando Axios y algunos medios de seguridad. Para evitar que alguien más dedique demasiado tiempo a resolver esto, déjame explicarte esto.

Necesitas hacer 3 cosas:

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

Estos pasos son en su mayoría factibles, pero se complican considerablemente por la relación del navegador con CORS. Un paso a la vez:

1. Configure su servidor (HTTP)

Cuando se emplea seguridad de transporte, la ejecución de JavaScript dentro de un navegador puede [por diseño] acceder solo a 6 de los encabezados HTTP enviados realmente por el servidor HTTP. Si queremos que el servidor sugiera un nombre de archivo para la descarga, debemos informarle al navegador que está "OK" para que se otorgue a JavaScript el acceso a otros encabezados donde se transportará el nombre de archivo sugerido.

Supongamos, por el bien de la discusión, que queremos que el servidor transmita el nombre de archivo sugerido dentro de un encabezado HTTP llamado X-Suggested-Filename . El servidor HTTP le dice al navegador que está bien exponer este encabezado personalizado recibido a JavaScript / Axios con el siguiente encabezado:

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

La forma exacta de configurar su servidor HTTP para configurar este encabezado varía de un producto a otro.

Consulte https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers para obtener una explicación completa y una descripción detallada de estos encabezados estándar.

2. Implementar el servicio del lado del servidor.

Su implementación de servicio del lado del servidor ahora debe realizar 2 cosas:

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

Esto se hace de diferentes maneras dependiendo de la pila de tecnología elegida. Dibujaré un ejemplo utilizando el estándar JavaEE 7 que debería emitir un informe de Excel:

@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(); }

El servicio ahora emite el documento binario (un informe de Excel, en este caso), establece el tipo de contenido correcto y también envía un encabezado HTTP personalizado que contiene el nombre de archivo sugerido para usar al guardar el documento.

3. Implementar un controlador de Axios para el documento recibido.

Hay algunos errores aquí, así que asegurémonos de que todos los detalles estén configurados correctamente:

  1. El servicio responde a @GET (es decir, HTTP GET), por lo que la llamada a axios debe ser ''axios.get (...)''.
  2. El documento se transmite como un flujo de bytes, por lo que debe decirle a axios que trate la respuesta como un Blob HTML5. (Es decir, tipo de respuesta: ''blob'' ).
  3. En este caso, la biblioteca de JavaScript del protector de archivos se utiliza para abrir el cuadro de diálogo del navegador. Sin embargo, usted podría elegir otro.

La implementación esquelética de Axios sería algo así como:

// 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); });

Estoy usando axios para solicitudes http básicas como obtener y publicar, y funciona bien. Ahora necesito poder descargar archivos de Excel también. Es esto posible con los axios. Si es así, ¿alguien tiene algún código de ejemplo? Si no, ¿qué más puedo usar en una aplicación de reacción para hacer lo mismo?


Cuando la respuesta viene con un archivo descargable, los encabezados de respuesta serán algo así como

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

Lo que puede hacer es crear un componente separado, que contendrá un iframe oculto.

import * as React from ''react''; var MyIframe = React.createClass({ render: function() { return ( <div style={{display: ''none''}}> <iframe src={this.props.iframeSrc} /> </div> ); } });

Ahora, puede pasar la URL del archivo descargable como prop a este componente, de modo que cuando este componente reciba prop, se volverá a representar y el archivo se descargará.

Editar: También puede utilizar el módulo de js-file-download . Enlace al repositorio de Github

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

Espero que esto ayude :)


El truco es hacer una etiqueta de anclaje invisible en el render() y agregar una ref React que permita activar un clic una vez que tengamos la respuesta de los axios:

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> ) } }

Aquí está la documentación: https://reactjs.org/docs/refs-and-the-dom.html . Puede encontrar una idea similar aquí: https://thewebtier.com/snippets/download-files-with-axios/ .


Mi respuesta es un hack total . Acabo de crear un enlace que parece un botón y le agrego la URL.

<a class="el-button" style="color: white; background-color: #58B7FF;" :href="<YOUR URL ENDPOINT HERE>" :download="<FILE NAME NERE>"> <i class="fa fa-file-excel-o"></i>&nbsp;Excel </a>

Estoy usando los excelentes VueJs por lo tanto, las VueJs impares, sin embargo, esta solución es VueJs del marco. La idea funcionaría para cualquier diseño basado en HTML.


Una solución más general.

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(); });

Echa un vistazo a las peculiaridades en https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743

Créditos completos a: https://gist.github.com/javilobo8


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. })