如果只是zip文件,用方案一即可,创建节点标签<a>,执行点击行为即可触发下载框。
方案一
js
const imgUrl = "zip文件地址";
//创建节点标签<a>,执行点击行为,拉原图
const link = document.createElement('a');
link.style.display = 'none';
link.href = imgUrl;
link.download = fileName; // 这里不再受跨域限制
document.body.appendChild(link);
link.click(); //触发下载
document.body.removeChild(link);
// 释放内存
setTimeout(() => URL.revokeObjectURL(imgUrl), 1000);
如果是图片资源,点击a标签可能会弹出图片预览窗口,解决思路是后端代理下载图片资源后,再在响应体修改Content-Type和Content-Disposition属性值,使浏览器识别为下载资源。
方案二
js
async download() {
// #ifdef H5
const imgUrl = "图片文件地址";
//获取文件名
const fileName = imgUrl.split('/').pop().split('?')[0]; // 可选
const proxyUrl = "URL化云对象方法地址"+`?url=${encodeURIComponent(imgUrl)}&filename=${encodeURIComponent(fileName)}`
//创建节点标签<a>,执行点击行为,拉原图
const link = document.createElement('a');
link.style.display = 'none';
link.href = proxyUrl;
link.download = fileName; // 这里不再受跨域限制
document.body.appendChild(link);
link.click(); //触发下载
document.body.removeChild(link);
// 释放内存
setTimeout(() => URL.revokeObjectURL(proxyUrl), 1000);
// #endif
}
云对象URL方法:
js
async download(params) {
const { url: remoteUrl, filename = 'download.jpg' } = params;
if (!remoteUrl) throw new Error('missing url');
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, '_'); //转为符合格式的文件名
// 1. 把远程文件拉回来,默认返回 Buffer
const res = await uniCloud.httpclient.request(remoteUrl, {
method: 'GET',
timeout: 10000
});
//console.log('返回类型:', Object.prototype.toString.call(res.data));
//console.log('字节长度:', res.data.length);
// 2. 组装响应头,强制下载
const headers = {
'Content-Type': 'application/octet-stream',
'Content-Disposition': `attachment; filename="${safeName}"`
};
// 3. 返回给前端
return {
mpserverlessComposedResponse: true, //自定义响应必带参数
statusCode: 200,
headers,
body:res.data,
isBase64Encoded: true
};