后台代码:
controller:
const fs = require('fs');
const path = require('path');
var request = require('request');
async downLoad() {
const { ctx } = this;
let url = ctx.query.url || null;
function downloadFile(url, filename, callback) {
var stream = fs.createWriteStream(filename);
request(url).pipe(stream).on('close', callback);
}
let extname = path.extname(url) || '.pdf'
let filename = Math.random().toString(36).substr(2) + new Date().getTime() + extname.toLocaleLowerCase();
let target = path.join(this.config.baseDir, 'static/pdf', filename);
await this.dirExists(path.join(this.config.baseDir, 'static/pdf'));
await new Promise(function (res, rej) {
downloadFile(url, target, function () {
res()
});
})
let extnames = {
".pdf": "application/pdf",
".png": "image/png",
".jpg": "image/jpeg",
".doc": "application/msword",
".zip": "application/zip",
".xls": "application/x-xls",
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
}
ctx.set('Content-Type', extnames[extname] || 'application/pdf')
ctx.body = fs.createReadStream(target)
ctx.status = 200;
fs.unlink(target, function (error) {
if (error) {
console.log(error);
return false;
}
})
}
// 以下来自 网上大佬的方法
/**
* 路径是否存在,不存在则创建
* @param {string} dir 路径
*/
async dirExists(dir) {
let isExists = await this.getStat(dir);
//如果该路径且不是文件,返回true
if (isExists && isExists.isDirectory()) {
return true;
} else if (isExists) { //如果该路径存在但是文件,返回false
return false;
}
//如果该路径不存在
let tempDir = path.parse(dir).dir; //拿到上级路径
//递归判断,如果上级目录也不存在,则会代码会在此处继续循环执行,直到目录存在
let status = await this.dirExists(tempDir);
let mkdirStatus;
if (status) {
mkdirStatus = await this.mkdir(dir);
}
return mkdirStatus;
}
/**
* 读取路径信息
* @param {string} path 路径
*/
getStat(path) {
return new Promise((resolve, reject) => {
fs.stat(path, (err, stats) => {
if (err) {
resolve(false);
} else {
resolve(stats);
}
})
})
}
/**
* 创建路径
* @param {string} dir 路径
*/
mkdir(dir) {
return new Promise((resolve, reject) => {
fs.mkdir(dir, err => {
if (err) {
resolve(false);
} else {
resolve(true);
}
})
})
}
router
router.get('/public/downLoad', middleware.checkHost(), controller.public.downLoad); // 下载
middleware
module.exports = () => {
return async function checkHost(ctx, next) {
let url = ctx.query.url;
let hosts = [
"17bxw.com",
"ccic-net.com.cn"
]
let isHost = false;
hosts.forEach((o, i) => {
if (url.indexOf(o) > -1) {
isHost = true;
}
})
if (isHost) {
await next();
} else {
ctx.body = {
value: '域名错误',
};
ctx.status = 302;
}
}
};
前端代码
// 参数说明
// url 远程地址 如:https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3140403455,2984550794&fm=26&gp=0.jpg
//fileName 文件下载名
function downloadWithBlob(url, fileName) {
if (url) {
var userAgent = navigator.userAgent
console.log(userAgent)
if (!!window.ActiveXObject || "ActiveXObject" in window) {
window.location.href = url;
return
};
try {
var eleLink = document.createElement('a')
eleLink.download = fileName || '文件'
eleLink.style.display = 'none'
eleLink.href = '/public/downLoad?url=' + url;
// 触发点击
document.body.appendChild(eleLink)
eleLink.click()
document.body.removeChild(eleLink);
} catch (e) {
}
} else {
layer.msg('下载失败')
}
}