Downloading Images Using Base64 Conversion
To download an image from a URL, convert it to a base64 string using a canvas element:
function convertImageToBase64(imageElement) {
const canvas = document.createElement('canvas');
canvas.width = imageElement.width;
canvas.height = imageElement.height;
const context = canvas.getContext('2d');
context.drawImage(imageElement, 0, 0, imageElement.width, imageElement.height);
const fileExtension = imageElement.src
.substring(imageElement.src.lastIndexOf('.') + 1)
.toLowerCase();
return canvas.toDataURL('image/' + fileExtension, 1);
}
const downloadLink = document.createElement('a');
downloadLink.setAttribute('download', 'qrCode');
const image = new Image();
image.src = res.data.qrCodeUrl + '?timestamp=' + new Date().getTime();
image.setAttribute('crossOrigin', 'Anonymous');
image.onload = () => {
downloadLink.href = convertImageToBase64(image);
downloadLink.click();
};
Hanlding Stream File Downloads
When downloading binary data, use Axios with responseType: 'blob' to handle the stream properly:
axios({
url: `xxx`,
method: 'get',
params: { ...searchData },
responseType: 'blob'
}).then(res => {
const downloadLink = document.createElement('a');
const fileBlob = new Blob([res.data], { type: 'application/vnd.ms-excel' });
// Extract filename from Content-Disposition header
const contentDisposition = res.headers['content-disposition'];
let fileName = 'download';
if (contentDisposition) {
const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
if (filenameMatch && filenameMatch[1]) {
fileName = decodeURIComponent(filenameMatch[1].replace(/['"]+/g, ''));
}
}
downloadLink.style.display = 'none';
downloadLink.href = URL.createObjectURL(fileBlob);
downloadLink.setAttribute('download', fileName);
document.body.appendChild(downloadLink);
downloadLink.click();
setTimeout(() => {
document.body.removeChild(downloadLink);
}, 0);
}).catch(err => {
console.log(err);
});
Handling Backend Error Responses
When backend errrors occur, they often return JSON instead of the expected binary data. Handle this case by checking the response type:
if (res.data.type === 'application/json') {
const reader = new FileReader();
reader.readAsText(res.data);
reader.onload = function(event) {
const errorData = JSON.parse(reader.result);
that.$message({
message: `Export failed: ${errorData.message}`,
type: 'error'
});
};
return false;
}
Note: When making CORS requests, the getResponseHeader() method only returns certain headers unless explicitly exposed via Access-Control-Expose-Headers. Add the following to your server response:
Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");