node.js学习笔记 - 文件上传(并用七牛云托管)

环境搭建

准备工作

提示:本文采用ts来构建环境,要是以js构建则取掉类型定义即可。

初始化项目
创建目录
	fileUpload-demo
		- dist 编译后文件
			- fileupload.html //上传文件静态页面	
		- src  存放源文件
		  - config.ts 配置文件
		  - handle-upload.ts 用户处理上传请求
		  - upload.ts 上传文件工具类
		- app.ts 入口文件
		- tsconfig.json  ts编译配置
> npm  init -y  //初始化项目

安装相关依赖

npm i koa koa-router busboy qiniu --save
npm i typescript -D
npm install @types/koa @types/koa-router

代码实现

  • 建立文件上传页面
    目录: dist/fileupload.html
	...省略
    <form action="api/music/upload" method="POST" enctype="multipart/form-data">
          <!-- input 中name 必须写... 不然busboy.on('file')无法监听 -->
        <input type="file" name="file"/> 
        <input type="submit" value="submit"/>
    </form>
  • 文件入口页面
    app.ts
import * as  Koa from 'koa'
import * as  Router from 'koa-router'
import * as  fs from 'fs'
import { upload } from './src/handle_upload'
const app = new Koa();
const router = new Router();

router.get('/', async ctx => {
  ctx.response.type = 'html'
  ctx.body = await fs.readFileSync(__dirname + '/fileupload.html', 'utf-8');
});
router.post('/upload', async ctx => {
   try {
    const res = await upload(ctx);
    ctx.body = { message: '上传成功', result: res };
  } catch (error) {
    ctx.body = { message: '上传失败', error };
  }
})
app.use(router.routes())
  .use(router.allowedMethods());

app.listen(3000, () => {
  console.log('listen at port 3000');
})
  • 处理上传文件请求
    src/handle_upload.ts

import * as path from 'path'
import {uploadFile} from './upload'
/**
 * 上传海报
 */

export const upload = async (ctx:any) => {
	const serverPath = path.join(__dirname, '../uploadtemp/');
	console.log(serverPath,'serverPath');
	// 获取上传图片
  const result:any = await uploadFile(ctx, {
    fileType: 'poster',
    path: serverPath
	})
	console.log(result,'图片信息');
	const imgPath = path.join(serverPath, result.imgPath)
  // 上传到七牛
	 const qiniu = await upToQiniu(imgPath, result.imgKey)
  // 上传到七牛之后 删除原来的缓存文件
	 removeTemFile(imgPath)
	return imgPath
}
  • 配置文件
    config.ts
	const QINIU = {
	accessKey: 'your_qn_accessKey',
	secretKey: 'your_qn_secretKey',
	bucket: 'naice',
	origin: 'xxxxxx',
	uploadURL: 'your_qn_uploadURL'
}

export {
  QINIU
}
  • 文件工具类
    src/upload.ts
    • 处理文件上传服务
/**
 * 同步创建文件目录
 * @param {*} dirname 目录绝对地址
 */
const mkdirsSync = (dirname:string) => {
  if (fs.existsSync(dirname)) {
    return true
  } else {
    if (mkdirsSync(path.dirname(dirname))) {
      fs.mkdirSync(dirname)
      return true
    }
  }
  return false;
}
//获取上传文件的后缀名
function getSuffix(fileName:string) {
  return fileName.split('.').pop()
}

// 重命名
function Rename(fileName:string) {
  return Math.random().toString(32).substr(4) + '.' + getSuffix(fileName)
}
// 删除文件
export const removeTemFile = (path:string) => {
  fs.unlink(path, (err) => {
    if (err) {
      throw err
    }
  })
}
	// 上传文件到服务
export const uploadFile = (ctx:any, options:any) => {
  const busboy = new Busboy({ headers: ctx.req.headers });
  //获取类型
  const fileType = options.fileType || 'image'
  const filePath = path.join(options.path, fileType)
  const mkdirResult = mkdirsSync(filePath)
  if (!mkdirResult) {
    return
  }
  console.log('start uploading...')
  return new Promise((resolve, reject)=> {
    //解析文件请求事件
    busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
      console.log('File [' + fieldname + ']: filename: ' + filename + ', encoding: ' + encoding + ', mimetype: ' + mimetype);
      const fileName = Rename(filename)
      const saveTo = path.join(path.join(filePath, fileName))
      //文件保存到特定路径
      file.pipe(fs.createWriteStream(saveTo))
      //解析文件结束
      file.on('end', function () {
        resolve({
          imgPath: `/${fileType}/${fileName}`,
          imgKey: fileName
        })
      })
    })

    busboy.on('finish', function () {
      console.log('finished...')
    })

    busboy.on('error', function (err:any) {
      console.log('err...')
      reject(err)
    })
    ctx.req.pipe(busboy)
  })
}
  • 添加七牛云上传方法
// 上传到七牛
export const upToQiniu = (filePath:string, key:string) => {
  const accessKey = myConfig.QINIU.accessKey
  const secretKey = myConfig.QINIU.secretKey
  const mac = new qiniu.auth.digest.Mac(accessKey, secretKey)
  const options = {
    scope: myConfig.QINIU.bucket
  }
  const putPolicy = new qiniu.rs.PutPolicy(options)
  const uploadToken = putPolicy.uploadToken(mac)

  const config:any= new qiniu.conf.Config()
  // 空间对应的机房 一定要按自己属区Zone对象
  config.zone = qiniu.zone.Zone_z0
  const localFile = filePath
  const formUploader = new qiniu.form_up.FormUploader(config)
  const putExtra = new qiniu.form_up.PutExtra()
  // 文件上传
  return new Promise((resolved, reject) => {
    formUploader.putFile(uploadToken, key, localFile, putExtra, function (respErr, respBody, respInfo) {
      if (respErr) {
        reject(respErr)
      } else {
        resolved(respBody)
      }
    })
  })
}

执行

  • 配置执行文件
    修改package.json
"scripts": {
    "temp":"tsc",
    "start":"node dist/app"
  },
  • 执行

npm run temp //将ts 编译成js文件
npm run start //启动项目

参考地址:
七牛云手册
koa学习笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值