node koa2实现上传图片并且同步上传到七牛云存储


Posted in Javascript onJuly 31, 2017

因为升级到新的node版本,之前的通过很多上传图片的方式都已经不适用了,所以自己就写了一个对于 koa2上传图片的小demo,记录一下心得。

废话不多说,下面直接上代码,里面都有注释。

const Koa = require('koa');
const route = require('koa-route');
const serve = require('koa-static');
const inspect = require('util').inspect
const path = require('path')
const os = require('os')
const fs = require('fs')
const Busboy = require('busboy')
const qiniu = require('qiniu')
const qiniuConfig = require('./qiniuconfig')

 
const app = new Koa();

app.use(serve(__dirname + '/public/'));

 
// 写入目录
const mkdirsSync = (dirname) => {
 if (fs.existsSync(dirname)) {
  return true
 } else {
  if (mkdirsSync(path.dirname(dirname))) {
   fs.mkdirSync(dirname)
   return true
  }
 }
 return false
}

function getSuffix (fileName) {
 return fileName.split('.').pop()
}

// 重命名
function Rename (fileName) {
 return Math.random().toString(16).substr(2) + '.' + getSuffix(fileName)
}
// 删除文件
function removeTemImage (path) {
 fs.unlink(path, (err) => {
  if (err) {
   throw err
  }
 })
}
// 上传到七牛
function upToQiniu (filePath, key) {
 const accessKey = qiniuConfig.accessKey // 你的七牛的accessKey
 const secretKey = qiniuConfig.secretKey // 你的七牛的secretKey
 const mac = new qiniu.auth.digest.Mac(accessKey, secretKey)

 const options = {
  scope: qiniuConfig.scope // 你的七牛存储对象
 }
 const putPolicy = new qiniu.rs.PutPolicy(options)
 const uploadToken = putPolicy.uploadToken(mac)

 const config = new qiniu.conf.Config()
 // 空间对应的机房
 config.zone = qiniu.zone.Zone_z2
 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)
   }
   if (respInfo.statusCode == 200) {
    resolved(respBody)
   } else {
    resolved(respBody)
   }
  })
 })

}

// 上传到本地服务器
function uploadFile (ctx, options) {
 const _emmiter = new Busboy({headers: ctx.req.headers})
 const fileType = options.fileType
 const filePath = path.join(options.path, fileType)
 const confirm = mkdirsSync(filePath)
 if (!confirm) {
  return
 }
 console.log('start uploading...')
 return new Promise((resolve, reject) => {
  _emmiter.on('file', function (fieldname, file, filename, encoding, 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
    })
   })
  })

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

  _emmiter.on('error', function (err) {
   console.log('err...')
   reject(err)
  })

  ctx.req.pipe(_emmiter)
 })
}



app.use(route.post('/upload', async function(ctx, next) {

  const serverPath = path.join(__dirname, './uploads/')
 // 获取上存图片
 const result = await uploadFile(ctx, {
  fileType: 'album',
  path: serverPath
 })
 const imgPath = path.join(serverPath, result.imgPath)
 // 上传到七牛
 const qiniu = await upToQiniu(imgPath, result.imgKey)
 // 上存到七牛之后 删除原来的缓存图片
 removeTemImage(imgPath)
 ctx.body = {
  imgUrl: `http://xxxxx(你的外链或者解析后七牛的路径)/${qiniu.key}`
 }
}));
 
app.listen(3001);

console.log('listening on port 3001');

然后在同一级目录下,创建一个public文件夹,然后在下面新建一个 index.html,因为我们上面已经把这个文件夹设置为静态访问文件夹了, public/index.html 的代码为

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <input id="btn1" type="file" name="file"/> 
 <input id="btn2" type="submit" value="提交"/>
</body>
<script>
  
  var btn1 = document.querySelector('#btn1')
  var btn2 = document.querySelector('#btn2')
  var file = null
  btn1.addEventListener('change', function(e){
    file = e.target.files[0]
  })

  btn2.onclick = function(){
  var _data = new FormData();
  _data.append('file', file);
  xhr(_data)
  }

  var xhr = function(formdata){
    var xmlHttp = new XMLHttpRequest(); 

    xmlHttp.open("post","http://127.0.0.1:3001/upload", true); 
     
    xmlHttp.send(formdata);

    xmlHttp.onreadystatechange = function(){ 
     if(xmlHttp.readyState==4){ 
       if(xmlHttp.status==200){ 
         var data = xmlHttp.responseText; 
         console.log(data); 
       } 
     }
    }
  }
</script>
</html>

选择好图片,然后点击提交,就可以上传到你的七牛空间啦!

源代码在 github: https://github.com/naihe138/koa-upload

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
分享别人写的一个小型js框架
Aug 13 Javascript
js综合应用实例简单的表格统计
Sep 03 Javascript
js生成的验证码的实现与技术分析
Sep 17 Javascript
jQuery实现简单的日期输入格式化控件
Mar 12 Javascript
JS中完美兼容各大浏览器的scrolltop方法
Apr 17 Javascript
JS实现自动变换的菜单效果代码
Sep 09 Javascript
jQuery Password Validation密码验证
Dec 30 Javascript
JS验证全角与半角及相互转化的介绍
May 18 Javascript
JS中关于正则的巧妙操作
Aug 31 Javascript
node puppeteer(headless chrome)实现网站登录
May 09 Javascript
vue生成token并保存到本地存储中
Jul 17 Javascript
Vue实现将数据库中带html标签的内容输出(原始HTML(Raw HTML))
Oct 28 Javascript
Angular.js初始化之ng-app的自动绑定与手动绑定详解
Jul 31 #Javascript
详解React中的组件通信问题
Jul 31 #Javascript
Angular.js前台传list数组由后台spring MVC接收数组示例代码
Jul 31 #Javascript
Angular.js中数组操作的方法教程
Jul 31 #Javascript
BootStrap导航栏问题记录
Jul 31 #Javascript
Angular4 中内置指令的基本用法
Jul 31 #Javascript
详谈ES6中的迭代器(Iterator)和生成器(Generator)
Jul 31 #Javascript
You might like
php不使用插件导出excel的简单方法
2014/03/04 PHP
php+mysql结合Ajax实现点赞功能完整实例
2015/01/30 PHP
php将数组存储为文本文件方法汇总
2015/10/28 PHP
PHP编写daemon process 实例详解
2016/11/13 PHP
PHP正则删除HTML代码中宽高样式的方法
2017/06/12 PHP
关于Laravel参数验证的一些疑与惑
2019/11/19 PHP
setTimeout 不断吐食CPU的问题分析
2009/04/01 Javascript
Mootools 1.2教程(3) 数组使用简介
2009/09/14 Javascript
Jquery遍历Json数据的方法
2015/04/20 Javascript
jQuery+CSS3折叠卡片式下拉列表框实现效果
2015/11/02 Javascript
如何动态加载外部Javascript文件
2015/12/02 Javascript
AngularJS中的指令全面解析(必看)
2016/05/20 Javascript
jquery 追加元素append、prepend、before、after用法与区别分析
2016/12/02 Javascript
vue.js 初体验之Chrome 插件开发实录
2017/05/13 Javascript
Node.js自定义实现文件路由功能
2017/09/22 Javascript
web前端vue之vuex单独一文件使用方式实例详解
2018/01/11 Javascript
node获取客户端ip功能简单示例
2019/08/24 Javascript
浅谈监听单选框radio改变事件(和layui中单选按钮改变事件)
2019/09/10 Javascript
Vue替代marquee标签超出宽度文字横向滚动效果
2019/12/09 Javascript
使用js实现单链解决前端队列问题的方法
2020/02/03 Javascript
Vue axios 跨域请求无法带上cookie的解决
2020/09/08 Javascript
解决vue2中使用elementUi打包报错的问题
2020/09/22 Javascript
用python删除java文件头上版权信息的方法
2014/07/31 Python
python中的多重继承实例讲解
2014/09/28 Python
Python读取sqlite数据库文件的方法分析
2017/08/07 Python
Python实现读取及写入csv文件的方法示例
2018/01/12 Python
Django 多语言教程的实现(i18n)
2018/07/07 Python
四川internet信息高速公路(C#)笔试题
2012/02/29 面试题
社区工作者先进事迹
2014/01/18 职场文书
责任书格式范文
2014/07/28 职场文书
九一八事变纪念日演讲稿
2014/09/14 职场文书
2015年小学生暑假总结
2015/07/13 职场文书
检讨书格式
2019/04/25 职场文书
详解如何使用Node.js实现热重载页面
2021/05/06 Javascript
解析目标检测之IoU
2021/06/26 Python
《杜鹃的婚约》OP主题曲「凸凹」无字幕影像公开
2022/04/08 日漫