Download pdf file from server response - javascript

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

Related

How to download a file from an api in react

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

PDF format is not getting downloaded using blob

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

React: How to open PDF in new Tab from Cloud storage without downloading in local pc

I am trying to open pdf from the cloud in a new tab, without downloading it to the local machine.
I tried this way but not working for me. In the new tab, it is giving an error.
function readFileInNewTab (fileId) {
let url = BASE_URL + "api/CMS/Documents/Download/" + fileId;
const requestOptions = {
method: 'GET',
headers: { 'Content-Type': 'application/pdf', ...authHeader(url) },
credentials: 'include',
responseType: "blob", // important
};
inProgress = true;
return fetch (url, requestOptions).then(handleResponse)
.then((response)=> {
const file = new Blob([response], { type: "application/pdf" });
//Build a URL from the file
const fileURL = URL.createObjectURL(file);
//Open the URL on new Window
const pdfWindow = window.open();
pdfWindow.location.href = fileURL;
})
.catch((error) => {
console.log(error);
});
}

Uploaded file is corrupt

I'm trying to upload a cropped image via client using fetch. The upload process works, the file size seems to be correct too but the uploaded image is corrupt and appears to be a white 16x16 square on the server. The file won't open when I download it (damaged or corrupt). I'm struggling to understand what I'm doing wrong. The back-end is Drupal.
Uploading files directly from an input using the same postFile function works without a problem.
const toFile = (blob) => {
blob.lastModifiedDate = new Date();
blob.name = 'cropped.png';
return blob;
}
const onCropperCrop = () => {
const imageElement = cropperRef?.current;
const cropper = imageElement?.cropper;
cropper.getCroppedCanvas().toBlob((blob) => {
const file = toFile(blob);
onCrop(file);
});
};
const onCrop = (file) => postFile(params);
export const postFile = async (
_file,
_uri,
_xcsrf_token,
_accessToken,
) => {
let formData = new FormData();
formData.append('File', _file);
let headers = {
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/octet-stream',
'Content-Disposition': 'file; filename="' + _file.name + '"',
'X-CSRF-Token': _xcsrf_token,
Authorization: 'Bearer ' + _accessToken,
},
};
return await fetch(_uri, {
method: 'POST',
headers: headers,
body: formData,
credentials: 'include'
});
};
The file object:

Creating PDF from request response doesn't work with axios but works in native xhr

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

Categories

Resources