Estoy usando este enfoque para descargar un archivo pdf del servidor (laravel 8 (api sanctum) + vue 3)
En el componente vue tengo esta funcion que descarga el archivo
const onDownloadDocument = (id) => { axios.post('/api/document/download', {id: id},{ responseType: 'blob' }).then(response => { let filename = response.headers['content-disposition'].split('filename=')[1] dLink.value.href = window.URL.createObjectURL(response.data) dLink.value.setAttribute('download',filename) dLink.value.click() }).catch(error => { console.log(error) })donde dLink es una referencia de enlace
const dLink = ref(null)en plantilla:
<a ref="dLink"/>Funciona este enfoque hasta hoy... después de actualizar el proyecto (actualización del compositor y actualización de npm)
Ahora, cuando hago clic para descargar el archivo (llame a la función onDownloadDocument), aparece un error:
contract.js:1049 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'responseType')¿Alguna idea de por qué?
El backend de API devuelve el archivo blob
return Storage::download($document->filename);Primero necesitas crear un blob y poner tu respuesta en él,
Y como dije en mi comentario, no necesita adjuntar una etiqueta de anclaje real, simplemente puede crear un elemento, adjuntarlo al cuerpo, simular el clic y eliminarlo de inmediato.
const blob = new Blob([response], {type: 'application/pdf'}) if (window.navigator['msSaveOrOpenBlob']) { window.navigator['msSaveBlob'](blob, filename) } else { const elem = window.document.createElement('a') elem.href = window.URL.createObjectURL(blob) elem.download = filename document.body.appendChild(elem) elem.click() document.body.removeChild(elem) }Esto me funciono, especifica a axios que estas esperando un blog, y listo:
axios({ url: 'http://localhost:5000/endpoint?', 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'); document.body.appendChild(link); link.click(); });