nodejs 文件下载(后端返回buffer,前端下载)

后端代码

async downloadFile() {
    const { ctx } = this;
    const body = ctx.request.body;
    const { id } = body;
    const fileRecord = await ctx.model.File.findOne({
      where: { id },
      attributes: ['path', 'suffix', 'md5_code', 'mime_type'],
      raw: true,
    });
    const file = fileRecord.path;
    try {
      fs.accessSync(file, fs.constants.F_OK);
    } catch (err) {
      console.log(`${file} does not exist`);
      return ctx.fail({ msg: '文件不存在' });
    }

    const reader = fs.createReadStream(file);
    const streamToBuffer = (stream) => {
      return new Promise((resolve, reject) => {
        const buffers = [];
        stream.on('error', reject);
        stream.on('data', (data) => buffers.push(data));
        stream.on('end', () => resolve(Buffer.concat(buffers)));
      });
    };
    const content = await streamToBuffer(reader);
    return ctx.success({
      result: {
        content,
        mime_type: fileRecord.mime_type,
        suffix: fileRecord.suffix,
        md5_code: fileRecord.md5_code,
      },
    });
  }
实例json
fileRecord
{
  path: 'D:\\app\\public\\upload\\20200525\\15903898530878733.jpg',
  suffix: '.jpg',
  md5_code: '15903898530878733',
  mime_type: 'image/jpeg'
}

返回结果

前端代码

export const downloadFile = async id => {
  let res = await axios.post("/api/file/download", { id });
const data
= res.result; let ab = new ArrayBuffer(data.content.data.length); let view = new Uint8Array(ab); for (var i = 0; i < data.content.data.length; ++i) { view[i] = data.content.data[i]; } const blob = new Blob([ab], { type: data.mime_type }); const filename = data.md5_code + data.suffix; if (window.navigator.msSaveOrOpenBlob) { navigator.msSaveBlob(blob, filename); } else { const link = document.createElement("a"); const body = document.querySelector("body"); link.href = window.URL.createObjectURL(blob); // 创建对象url link.download = filename; // fix Firefox link.style.display = "none"; body.appendChild(link); link.click(); body.removeChild(link); window.URL.revokeObjectURL(link.href); // 通过调用 URL.createObjectURL() 创建的 URL 对象 } };

 Nodejs中ArrayBuffer 与 Buffer的互相转换(参考 https://www.jianshu.com/p/2b57264d1327)

Buffer  => ArrayBuffer

function toArrayBuffer(buf) {
    var ab = new ArrayBuffer(buf.length);
    var view = new Uint8Array(ab);
    for (var i = 0; i < buf.length; ++i) {
        view[i] = buf[i];
    }
    return ab;
}

ArrayBuffer => Buffer

function toBuffer(ab) {
    var buf = new Buffer(ab.byteLength);
    var view = new Uint8Array(ab);
    for (var i = 0; i < buf.length; ++i) {
        buf[i] = view[i];
    }
    return buf;
}

猜你喜欢

转载自www.cnblogs.com/xiaosongJiang/p/12957524.html