Here is the Javascript code
function DownloadFromUrl(url, mime) {
axios({
url: 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.' + mime);
document.body.appendChild(link);
link.click();
});
}
$("#dl_file").click(() => {
DownloadFromUrl("http://www.africau.edu/images/default/sample.pdf", "pdf");
});
Here is HTML code
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js">
<button id="dl_file">
Download File
</button>
Here is the jsfiddle link : https://jsfiddle.net/maayuresh/uzfsgjet/2/
So I did this not too long ago, also with Axios but had some slightly different settings.
The main thing is that the responseType sent in the request was set to 'arraybuffer' and when processing the response I provided the mimeType when creating the Blob new Blob([result.data], { type: 'application/pdf' });.
Related
So, I am creating a docx with php laravel, then converting to pdf and save it in my public server folder. Finally, I am sending a response to my client with the file.
Now, in client side, I am tryng to download it.
It's half working, because I can download a file (with exact same page number) but the file and all the page are blank page.
Here, server side sending my file to client side
$docx->transformDocument($fileName . '.docx', $fileName . '.pdf');
return response()->file(public_path($fileName . '.pdf'));
What I have tried client side
export const generateDocx = (offerData) => async () => {
await axios({
method: 'post',
url: `${process.env.REACT_APP_API_URL2}offer/generate/docx`,
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
responseType: 'arraybuffer',
},
data: offerData,
}).then((res) => {
console.log(res);
// Create blob link to download
const url = window.URL.createObjectURL(new Blob([res.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `FileName.pdf`);
document.body.appendChild(link);
link.click();
link.parentNode.removeChild(link);
});
};
what my console.log (res) contain :
I have also tried this :
let fileName = 'aaa.pdf';
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(
new Blob([res.data], {
type: 'application/pdf',
encoding: 'UTF-8',
responseType: 'blob'
}),
fileName
);
} else {
const url = window.URL.createObjectURL(
new Blob([res.data], {
type: 'application/pdf',
encoding: 'UTF-8',
})
);
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
link.remove();
}
console.log(res.data);
});
And with file-saver package
var blob = new Blob([res.data], {
type: 'application/pdf',
});
saveAs(blob, 'hello world.pdf');
});
what my blob console.log contain :
After some test it's working
export const generateDocx = (offerData) => async () => {
await axios({
method: 'post',
url: `${process.env.REACT_APP_API_URL2}offer/generate/docx`,
responseType: 'blob',
headers: {
Accept: 'application/pdf',
},
data: offerData,
}).then((res) => {
var blob = new Blob([res.data], {
type: 'application/pdf',
});
saveAs(blob, 'test.pdf');
});
};
thank you all for your help
How to download a file from an API response which is in a different format ?
await axios.get(`/dashboard/reportdownload/?file_name=242424242.pdf`,{
headers: {
"Authorization": `Bearer 767958756576576576jgjhgjhg`
}
})
.then((res) => {
console.log(res?.data);
});
In response I am getting
How do download it with reactjs
You need to check if the response from the API is of type blob, then convert it. For example, if it is clear you are expecting a PDF response, try this:
await axios.get(`/dashboard/reportdownload/?file_name=242424242.pdf`, {
headers: {
'Authorization': `Bearer 767958756576576576jgjhgjhg`
}
})
.then((response) => {
let fileName = '242424242.pdf';
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
// IE variant
window.navigator.msSaveOrOpenBlob(
new Blob([response.data], {
type: 'application/pdf',
encoding: 'UTF-8'
}),
fileName
);
} else {
const url = window.URL.createObjectURL(
new Blob([response.data], {
type: 'application/pdf',
encoding: 'UTF-8'
})
);
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
link.remove();
}
});
I have a webserver that is using flask.
To download a file from the webServer, I have the following code:
#images_api_blueprint.route('/api/v1_2/download_file3', methods=['GET'])
def download_file3():
zipFullFileName1 = './foo.zip'
response1 = send_file(zipFullFileName1, as_attachment=True)
return response1
If I type "http://localhost/api/v1_2/download_file3" in the browser, the file is downloaded - good!
But I need to trigger the download programatically from my client via javascript.
When I click on a button, I reach the code below, which triggers the same url as above,
this.downloadFile3 = function (layer, zipFilename) {
let queryUrl = 'http://localhost/api/v1_2/download_file3';
fetch(queryUrl, {
method: 'get'
})
.then(function(response) {
return response;
})
.catch((err) => {
console.error('error from api/v1_2/download_file3', err);
reject(false);
});
};
But when triggering via javascript, the file is not downloaded.
What am I doing wrong?
Thanks,
Avi
Get a blob and then you can use
function downloadFile(blob, fileName)
{
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
var url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
}
or using jquery
$.ajax({
url: requestUrl,
processData: false,
dataType: 'datatype-here'
}).done(function(data) {
var blob = new Blob([data], { type: "image/png; encoding=utf8" });
saveData(blob, 'filename.png');
});
I would like to add a filename to my Blob file, but I don't really know how to do it, here is my code for the moment :
onClick() {
var myHeader = new Headers();
myHeader.append('Content-Type', 'text/plain');
fetch(this.props.url, {
method: 'POST',
headers: myHeader,
body: JSON.stringify(this.state.api_arg)
}).then(response => {
const filename = getFileName(response.headers.get('Content-Disposition'))
response.blob().then(myBlob => {
const fileUrl = URL.createObjectURL(myBlob)
console.log(fileUrl)
window.open(fileUrl)
})
})
}
my filename is stocked in a variable.
The answer of Niels was incomplete, to handle filename in blob you have to do it that way:
const file = new File([myBlob], filename)
const url = URL.createObjectURL(myBlob);
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
In order to force download PDF from server I tried to use axios and native xhr object. The reason is that I have to send post request, because I pass too much data to server, so the option with simple link (like site.ru/download-pdf won't work for me).
Even though I finally managed to do this with Xhr, I still don't have a clue why axios way doesn't work.
Here is how I do this with xhr and it works for me:
let xhr = new XMLHttpRequest()
xhr.open('POST', Vue.config.baseUrl + `order-results/${id}/export-pdf`, true)
xhr.setRequestHeader("Authorization", 'Bearer ' + this.token())
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
xhr.responseType = 'arraybuffer'
xhr.onload = function(e) {
if (this.status === 200) {
let blob = new Blob([this.response], { type:"application/pdf" })
let link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = 'Results.pdf'
link.click()
}
};
xhr.send("data=" + data);
Here is "axios-way" and I actually get PDF with correct number of pages, but they are all empty:
axios.post(`order-results/${id}/export-pdf`, {
data,
responseType: 'arraybuffer'
}).then((response) => {
let blob = new Blob([response.data], { type:"application/pdf" })
let link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = 'Results.pdf'
link.click()
})
Axios is already configured to send Authorization token.
I put Application/x-www-form-urlencoded in xhr because otherwise I couldn't get data in server side.
Even though xhr works, I'd prefer to use axios since I use it everywhere and I'm just curios what I'm doing wrong. I tried different solutions, and only native xhr did the job.
The following works for me:
axios.post("http://localhost:8080/reports/my-report/",
data,
{
responseType: 'arraybuffer',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/pdf'
}
})
.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();
})
.catch((error) => console.log(error));
Let me know if this helps.
Cheers!
For whatever reason the pdf is downloading but any content passed is not appearing resulting in a blank pdf.
I found this code snippet that is similar but results in a pdf with content.
axios({
url: '/pdf',
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();
});
there was some feedback stating that it didnt work on IE 11, I have not tested it but a solution was posted using FileSaver.js
axios({
url: '/pdf',
method: 'GET',
responseType: 'blob', // important
}).then((response) => {
FileSaver.saveAs(new Blob([response.data]));
});
There is a special responseType: 'blob':
axios.post(`order-results/${id}/export-pdf`, {
data,
responseType: 'blob'
}).then((response) => {
let link = window.URL.createObjectURL(blob)
link.download = 'Results.pdf'
link.click()
})
Or you can use window.open method:
axios.post(`order-results/${id}/export-pdf`, {
data,
responseType: 'blob'
}).then((response) => {
window.open(URL.createObjectURL(response.data));
})
You're getting empty PDF 'cause no data is passed to the server. You can try passing data using data object like this
axios.post(`order-results/${id}/export-pdf`, {
data: {
firstName: 'Fred'
},
responseType: 'arraybuffer'
}).then((response) => {
console.log(response)
let blob = new Blob([response.data], { type: 'application/pdf' } ),
url = window.URL.createObjectURL(blob)
window.open(url); // Mostly the same, I was just experimenting with different approaches, tried link.click, iframe and other solutions
});
By the way I gotta thank you so much for showing me the hint in order to download pdf from response. Thank ya :)
var dates = {
fromDate: 20/5/2017,
toDate: 25/5/2017
}
The way in which I have used is,
axios({
method:'post',
url:'/reports/interval-dates',
responseType:'arraybuffer',
data: dates
})
.then(function(response) {
let blob = new Blob([response.data], { type: 'application/pdf' } );
let link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'Report.pdf';
link.click();
});