需求:展示图片,且支持点击触发下载图片
问题:浏览器对可预览的文件,如图片、pdf、txt等文件,默认直接预览文件,而不是触发下载
前端解决方案:
1.利用canvas将图片转换为base64编码
(通过将图片绘制到canvas中,然后将canvas对象转换为base64编码,从而实现图片转为base64编码)
将图片转换为base64位编码有什么好处?
- 将图片转换为base64位编码后,图片会跟随代码(html、css、js)一起请求加载,不会再单独进行请求加载;
- 可以防止由于图片路径错误导致图片加载失败的问题;
/* 下载图片 */
const downloadIamge = (imgsrc, name) => {
const image = new Image()
// 允许资源跨域使用
image.setAttribute('crossOrigin', 'anonymous')
image.src = imgsrc
image.onload = () => {
// 利用canvas将图片转换为base64编码
const canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
const context = canvas.getContext('2d')
context?.drawImage(image, 0, 0, image.width, image.height)
// 将canvas对象转换为base64位编码
const url = canvas.toDataURL('image/png')
// 点击触发下载
const a = document.createElement('a')
const event = new MouseEvent('click')
a.download = name || 'Certificate'
a.href = url
a.dispatchEvent(event)
}
}
后端解决方案:
这就是Content-Disposition设置的问题,如下都是java示例:
设置为inline,如果浏览器支持该文件类型的预览,就会打开,而不是下载:
response.setHeader("Content-Disposition", "inline; filename=111.jpg");
设置为attachment,浏览器则直接进行下载,纵使他能够预览该类型的文件。
response.setHeader("Content-Disposition", "attachment; filename=111.jpg");
特别说明:Chrome不设置Content-Type也会自动打开,如果是它可识别预览的文件。