How can I fix this image download error in javascript? - javascript

This is my code:
function downloadImage(url) {
fetch(url, {
mode: 'no-cors',
})
.then(response => response.blob())
.then(blob => {
let blobUrl = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.download = url.replace(/^.*[\\\/]/, '');
a.href = blobUrl;
document.body.appendChild(a);
a.click();
a.remove();
})
}
var url = 'https://c4.wallpaperflare.com/wallpaper/203/636/834/minimalism-landscape-digital-
windows-11-hd-wallpaper-preview.jpg';
downloadImage(url)
i can successfully download the image but when I open the image it's shows Sorry, Photos can't open this file because the format is currently unsupported, or the file is corrupted
When I use unsplash image url in that time it's work well. Can anyone tell me please why it's happening and how can I fix this issue.

The issue here is the Response object , fetch is being called with mode:'no-cors', resulting in the response object to have type as "opaque" and hence using response.blob() will result into a Blob size of 0 and Blob type of "" (read more below in Response.blob()).
The mime-type is set as expected and your code works as expected but since you are making a cross origin request you are getting Response.blob() as empty and the file you subsequently save(download through anchor tag) has no data.
Read more about Response.blob()
Read more about Response.type
Read more about CORS Protocol
to validate the above try and console.log the blob like so :
function downloadImage(url) {
fetch(url, {
mode: 'no-cors',
})
.then(response => response.blob())
.then(blob => {
console.log(blob); //log the blob and check its size;
let blobUrl = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.download = url.replace(/^.*[\\\/]/, '');
a.href = blobUrl;
document.body.appendChild(a);
a.click();
a.remove();
})
}

Do like this because you're not defining MIME type while downloading the file.
return fetch(urlEndpoint, options)
.then((res) => res.blob())
.then((blob) => URL.createObjectURL(blob))
.then((href) => {
Object.assign(document.createElement('a'), {
href,
download: 'filename.png',
}).click();
});
or else you can do like this
download(filename,url) {
fetch(url, {
mode: 'no-cors',
})
.then(response => response.blob())
.then(blob => URL.createObjectURL(blob))
.then(uril => {
var link = document.createElement("a");
link.href = uril;
link.download = filename + ".png";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
}

Related

View or download PDF from Api Rest fetch

I am trying to finish a download of a PDF from an API Rest. I can't see the pdf completely in a new browser tab, I get a chorme pop up with the message "Error
An error occurred while loading the PDF document."
I have the following:
function download_2() {
var myHeaders = new Headers();
myHeaders.append(
"Authorization",
"mytokennnnnnnnnnnnn"
);
var requestOptions = {
method: "GET",
headers: myHeaders,
redirect: "follow",
};
fetch(
"myAPIRESTurlurlurlurlurl",
requestOptions
)
.then((response) => response.text())
.then((result) => {
let blob = new Blob([result.data], { type: "application/pdf" });
var arrayBuff;
var fileReader = new FileReader();
fileReader.onload = function (event) {
arrayBuff = event.target.result;
};
fileReader.readAsArrayBuffer(blob);
var URL = window.URL || window.webkitURL;
const url = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.target = "_blank";
link.href = url;
//I apend the link element
document.body.appendChild(link);
//download
link.click();
// Clean and remove the link
link.parentNode.removeChild(link);
URL.revokeObjectURL(url);
})
.catch((error) => console.log("error", error));
}
I've also used the fileReader to then pass the blob to it, but I'm not sure if I'm doing it right.
Thank you for the help.
Regards.
Did you try to add the download="true" attribute to the href tag you created ?

Unable to select text in pdf when downloading from NGINX server

I have the following code in a NodeJS app using the library node-html-pdf:
pdf.create(PDF_html).toStream((err, pdfStream) => {
if (err) {
console.log(err)
return res.sendStatus(500)
} else {
res.statusCode = 200
res.setHeader('Content-type', 'application/pdf')
res.attachment()
pdfStream.on('end', () => {
return res.end()
})
pdfStream.pipe(res)
}
})
On the client side I am using fetch to retrieve and download the PDF using the following code:
document.getElementById('pdf_button').addEventListener("click", function() {
let query_nr = ''
let query_spnr = ''
let url = 'https://{my.public.server.url}/getPDF/'
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"nr": query_nr,
"spnr": query_spnr
})
})
.then((response) => response.blob())
.then((blob) => {
blob = new Blob([blob], {type: "application/pdf"});
const objectURL = URL.createObjectURL(blob);
const a = document.createElement("a")
document.body.appendChild(a)
a.style = "display: none"
a.href = objectURL
a.type = 'application/pdf'
a.download = query_nr + '-' + query_spnr + '.pdf'
console.log(a);
a.click()
// window.open(objectURL, '_blank');
})
.catch((error) => {
console.error(error);
})
});
The above code works fine as long I am using localhost as url, and I am able to select text from the downloaded text.
When I download the PDF from the server it seems like the whole PDF-file gets converted to an image (I might be very wrong), and I am not able to select any text.
Does anyone know how I can fix this? And why is this happening?

How to download excel file with axios vuejs?

On the controller I return a path to where the excel file is located..Now I want to download that file
Below is my code:
reportExcel(val) {
axios
.get("/algn/api/report/" + val)
.then((res) => {
var url = res.data; // http://localhost.local/public/files/data.xlsx
const a = document.createElement("a");
a.href = url;
a.download = url.split("/").pop();
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
})
.catch((error) => {
console.log(error);
});
},
I am getting the error as "Excel cannot open the file "data.xlsx" because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file". (The original excel file is still usable).
I have tried all the solutions which I found in google but nothing worked. Please help. Thanks
Try this:
reportExcel(val) {
axios
// add responseType
.get("/algn/api/report/" + val, {responseType : 'blob'})
.then((res) => {
const url = window.URL.createObjectURL(new Blob([res]));
const a = document.createElement("a");
a.href = url;
const filename = `file.xlsx`;
a.setAttribute('download', filename);
document.body.appendChild(link);
a.click();
a.remove();
})
.catch((error) => {
console.log(error);
});
},
Assuming the link gives correct excel file, we can inform that it is file (not the usual JSON) by specifying {responseType : 'blob'} in the request. Then, create the file using window.URL.createObjectURL(new Blob([res])). The rest is small adjustments to handle file instead of text.

Open blob file stored in indexDB on ios/Ipad

Hello i download file using axios like so.
return axios({
method: "get",
url: URL,
responseType: "blob",
})
.then((response) => {
return {
...val,
blob: response.data,
};
})
.catch((_) => {
onError(val);
});
After that i store it in indexDB using Dexie.
const { id } = dataToSave;
return db.files.put(dataToSave, id);
I have file in db like blob
Next i want to save it like so:
download(myBlob, title, mimeType);
i try using filesaver,downloadjs or manualy
const { title, blob, mimeType } = material;
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.style.display = "none";
a.href = url;
// the filename you want
a.download = title;
document.body.appendChild(a);
a.click();
setTimeout(() => {
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
}, 1000);
It will download file only right after i download it to blob (browser session).
When i refresh page i get error WebkitBlobResource:1.
Any workaround of problem ? To either download file (pdf,html) or open it in new or same tab.
For now store data as arraybuffer, not blob works.

VueJs $router not working after download .docx from Axios request using Blob

Here is my function:
After link.click() document downloaded but this.$router.push() stop working. What is the problem?
axios.post(apiurl + "api/appform-list/",
{
this.data
},
{
responseType: "arraybuffer",
}
)
.then((response) => {
let blob = new Blob([response.data]),
url = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", "GeneratedDoc.docx");
document.body.appendChild(link);
link.click();
this.RemoveInputs();
this.$router.push("/clientlist");
})
.catch(function (error) {
console.log(error)
});

Categories