The issue was with the axios instance.
I have added response type to the request header, the issue was solved.
responseType: "blob",
this was the root cause. After that I was able to download the file with response provided by 'Klian' in the comments to my question.
Answer from Nabeel Mhd on Stack OverflowThe issue was with the axios instance.
I have added response type to the request header, the issue was solved.
responseType: "blob",
this was the root cause. After that I was able to download the file with response provided by 'Klian' in the comments to my question.
You can try using the FileSaver.js library to download the file.
Here is the sample code:
import FileSaver from 'file-saver';
// Call your API to get the response
axios.get('/PrintWorkSheet', { responseType: 'arraybuffer' }).then((response) =>
{
//Create a Blob object from the response data
const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
// Use FileSaver.js to save the Blob as a file
FileSaver.saveAs(blob, 'WorkSheet.xlsx');
})
.catch((error) => {
console.log(error);
});
I'm working with an API res that contains a zip, csv, and pdf. I've been researching how I should download and/or create download buttons for these files but a lot of articles I'm looking through specify that their method is 'hacky' (or something similar).
I don't like the idea of pushing a 'hacky' solution to production. It may be a starting point but not really a good foundation to build off of. Does anybody know of good practices for this kind of procedure?
I've boiled it down to:
-
Parse the response
-
Store the file contents
-
Create sources for the downloads
but surely it isn't that simple, right?
Videos
Apologies if I am not using the right terms to explain.
I am building some public API endpoints which will request data from another service. The response is a stream of data. How can I trigger download action (since there is no client side js in work, I doubt I can use any HTML tags to do it.)
Tried setting the disposition header but it did not help either.
I believe I should store this stream response somewhere like s3 or some cloud storage and trigger the download from there or can I send a zip file as a response?
EDIT: The disposition header worked with a get call. Thanks for helping out.
It also works with post I think but I will test that at a later point.
I am not completely sure of what you are trying to do, but I would recommend using Guzzle to send an HTTP request to an external API. It is easy to install using composer on your Laravel application.
As it is explained in Using Responses you can access your response body (in this case the contents of a .pdf file) like this:
$body = $response->getBody();
// Explicitly cast the body to a string
$stringBody = (string) $body;
and then you can use the Laravel File System to store the file on your local storage doing something like this:
Storage::disk('local')->put('Invoice_12345-234566.pdf', $stringBody);
As it is explained in The Local Driver.
There is one solution i was using in my case.
You should download external image using copy() function, then send it to user in the response:
$fileSource = $jsonDecodedResults['result']['invoice']['src'];
$headers = ['Content-Type: application/pdf'];
$tempFile = tempnam(sys_get_temp_dir(), $fileSource);
copy(**YOUR_TEMP_Directory**, $tempFile);
return response()->download($tempFile, $fileName, $headers);
The response.data returned from Axios is a JSON string. So creating a Blob from that JSON doesn't produce the correct object. From the Axios docs:
//
responseTypeindicates the type of data that the server will respond with
// options are: 'arraybuffer', 'document', 'json', 'text', 'stream'
// browser only: 'blob'
responseType: 'json', // default
The simple fix is to tell Axios to provide the response in the form of a Blob. Then the URL.createObjectURL() will produce a URL to a file that is in the correct format.
axios.post('api/downloadMyFile', data, { responseType: 'blob' })
.then(blob=>{
const url = window.URL.createObjectURL(blob.data);
const a = document.createElement('a');
a.href = url;
a.download = "download.zip"
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
})
try this two lines to get the file name from the response object
var filename = response.headers.get("content-disposition");
filename = filename.match(/(?<=")(?:\\.|[^"\\])*(?=")/)[0];