node文件上传下载,前端文件上传下载

node中的文件上传与下载

目前项目中常见的文件上传和下载的方式采用的是formData和文件流下载,本文也介绍通过node进行文件的上传和下载处理.
文件流的下载

文件上传

1.文件流上传

//获取上传文件
 const file = ctx.request.files.file;
// 读取文件流
const fileReader = fs.createReadStream(file.path);
const filePath ='./public/upload';
// 组装成绝对路径
const fileResource = filePath + `/${file.name}`;
/*
使用 createWriteStream 写入数据,然后使用管道流pipe拼接
*/
const writeStream = fs.createWriteStream(fileResource);
// 判断 /static/upload 文件夹是否存在,如果不在的话就创建一个
if (!fs.existsSync(filePath)) {
 fs.mkdir(filePath, (err) => {
   if (err) {
     throw new Error(err);
   } else {
     fileReader.pipe(writeStream);
     ctx.body = {
         url: `http://${getLocalIP()}:3001/public/upload` + `/${file.name}`,
       code: 0,
       message: '上传成功'
     };
   }
 });
} else {
 fileReader.pipe(writeStream);
 ctx.body = {
   url: `http://${getLocalIP()}:3001/public/upload` + `/${file.name}`,
   code: 0,
   message: '上传成功'
 };
}

2.koa-multer上传

注意这种上传方式 不能使用koa-body插件 可以使用koa-bodyparser, 因为koa-body和koa-multer有冲突
//配置
const multer = require('koa-multer');
const path = require('path');

const storage = multer.diskStorage({
    //设置上传的文件夹
destination:'public/uploads/'+new Date().getFullYear() + (new Date().getMonth()+1) + new Date().getDate(),
 filename(ctx,file,cb){
  //设置文件名称
 const filenameArr = file.originalname.split('.');
 cb(null,Date.now() + '.' + filenameArr[filenameArr.length-1]);
}
});

const upload = multer({storage});   
router.post('/upoload',upload.single('file'),async(ctx,next)=>{
 //上传成功
})

文件下载

1.文件流下载
1).使用语与所有文件下载
//文件下载地址

 const filePath = path.join(__dirname, 'package.json');
 
     let fileData= await new Promise((resolve,reject)=>{
         //异步读取文件
         fs.readFile(filePath,{encoding:"utf-8"},(error,data)=>{
              if(error){
                  reject(error)
              } else{
                  resolve(data)
              }
         })
       })
       //设置文件的相应头
       ctx.set('Content-type', 'application/octet-stream');
 ctx.set('Content-Disposition', `'attachment;filename=package.json`); 
 //改成二进制文件传送,前端通过blob进行接收下载
 let buf=Buffer.from(JSON.stringify(fileData))
   ctx.body =buf

2.不适用json格式的文件下载
```javascript
const filePath = path.join(__dirname+'/public/upload/', 'Code.exe');   
 let file = fs.createReadStream(filePath);
 try {
   await new Promise((resolve, reject) => {
     file.on('open', function () {
       // 没有特定类型的二进制文件,使用 application/octet-stream
       ctx.set('content-type', 'application/octet-stream');
       ctx.set('Content-Disposition', `'attachment;filename=Code.exe`);
       console.log(file)
       ctx.body = file;
       resolve();
     });
     file.on('error', function (err) {
       reject(err);
     })
   });
 } catch (e) {
   console.error(e);
   next();
 }

//还有这种方式

 ctx.set('content-type', 'application/octet-stream');
  ctx.set('Content-Disposition', `'attachment;filename=Code.exe`);
  ctx.body = await readFile()


  function readFile() {
    return new Promise(resolve => {
      const filePath = path.join(__dirname + '/public/upload/', 'Code.exe');
      let readStream = fs.createReadStream(filePath);
      const buffers = [];
      readStream.on('data', function (buffer) {
        buffers.push(buffer);
      });
      readStream.on('end', function () {
        const data = Buffer.from(buffers);
        resolve(data)

      });
      readStream.on('error', function (error) {
        console.error('readStream error:', error.message);
      })
    })
  }

2.koa-send下载(直接返回下载内容)
const path = public/upload/package.json;
// fileStream.on(‘data’, function (data) {
ctx.set(‘Content-type’, ‘application/octet-stream’);
ctx.set(“Content-disposition”, “attachment; filename=package.json” )

await send(ctx, path)


 ## 前端常见的文件上传下载
 ### 文件上传
 ####  原生input  formData
  ```javascript
      <input type="file" id="file" @change="handleADD">
       handleADD(e){
        
       let file=e.target.file
       let formData=new FormData()
       formData.append('file',file)
      //发送地址
  axios.get('api地址',formData)

from 表单提交

<form action="上传地址" methods="post" enctype="mulipart/form-data">
<input type="file" name="file"/>
</form>

el-upload
  <el-upload
class="upload-demo"
action="/api/file/upload/"

multiple
:limit="3"
:on-success="handleSucces"
:file-list="fileList">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
//这种方式 我们也可以进行参数的添加(在data属性中)添加请求头(headers属性中)

文件下载

a标签直接下载
a标签直接下载 这种一般是服务端直接返回文件内容的方式,对应koa-send的方式或者文件流第二种方式
直接下载

地址栏输入文件URL
window.location.href = URL
window.open(URL)

bolo下载 使用于文件流下载·
 let type=res.headers['content-disposition'].split(';')[1].split('=')[1]
                 let blob=new Blob([res.data])
                  const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = type;
      // 兼容旧版本火狐浏览器,将 a 标签插入 DOM 中
      document.body.appendChild(a);
      a.click();
      a.remove();

fs中 readFile(path,fb)//异步读取文件
///路径问题 node中的相对路径则相对的是运行node文件的目录。
//__dirname 则表示的是当前文件的文件夹目录 fileName则是包含当前文件的路径
path.join(a,b)则是将多个路径片段通过\链接起来,形成新的完整路径 path.resolve(/a,/b) 把一个路径解析成一个绝对路径 /则代表根路径

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值