图片点击下载而非预览
实现点击图片链接触发下载,而不是在浏览器中打开预览
问题
网站中的图片链接,点击后浏览器默认会打开预览。如何让用户点击后直接触发下载?
解答
方案一:使用 download 属性(同源)
<!-- download 属性可指定下载文件名 -->
<a href="/images/photo.jpg" download="my-photo.jpg">下载图片</a>
<!-- 不指定文件名,使用原文件名 -->
<a href="/images/photo.jpg" download>下载图片</a>
注意:download 属性仅对同源 URL 有效,跨域资源会被忽略。
方案二:Blob 下载(支持跨域)
/**
* 下载图片
* @param {string} url - 图片地址
* @param {string} filename - 保存的文件名
*/
async function downloadImage(url, filename) {
try {
// 获取图片数据
const response = await fetch(url);
const blob = await response.blob();
// 创建 Blob URL
const blobUrl = URL.createObjectURL(blob);
// 创建隐藏的 a 标签并触发点击
const link = document.createElement('a');
link.href = blobUrl;
link.download = filename;
link.click();
// 释放 Blob URL
URL.revokeObjectURL(blobUrl);
} catch (error) {
console.error('下载失败:', error);
}
}
// 使用示例
downloadImage('https://example.com/photo.jpg', 'photo.jpg');
方案三:服务端设置响应头
# Nginx 配置
location /downloads/ {
add_header Content-Disposition "attachment";
}
// Node.js Express
app.get('/download/:filename', (req, res) => {
const file = `./images/${req.params.filename}`;
res.download(file); // 自动设置 Content-Disposition: attachment
});
完整组件示例
<!DOCTYPE html>
<html>
<body>
<button onclick="download()">下载图片</button>
<script>
function download() {
const url = 'https://picsum.photos/200/300';
const filename = `image-${Date.now()}.jpg`;
fetch(url)
.then(res => res.blob())
.then(blob => {
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = filename;
a.click();
URL.revokeObjectURL(a.href);
});
}
</script>
</body>
</html>
关键点
download属性只对同源资源有效,跨域会失效- 跨域下载需要先 fetch 获取 blob,再通过 blob URL 下载
- 使用后记得调用
URL.revokeObjectURL()释放内存 - 服务端可通过
Content-Disposition: attachment响应头强制下载 - 跨域 fetch 需要服务端配置 CORS
目录