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 相关文章推荐
parseInt parseFloat js字符串转换数字
Aug 01 Javascript
html+css+js实现xp window界面及有关功能
Mar 26 Javascript
yui3的AOP(面向切面编程)和OOP(面向对象编程)
May 01 Javascript
jQuery过滤HTML标签并高亮显示关键字的方法
Aug 07 Javascript
解决js函数闭包内存泄露问题的办法
Jan 25 Javascript
AngularJS打开页面隐藏显示表达式用法示例
Dec 25 Javascript
JavaScript运动框架 多值运动(四)
May 18 Javascript
Angular弹出模态框的两种方式
Oct 19 Javascript
vue 弹框产生的滚动穿透问题的解决
Sep 21 Javascript
Vue中使用canvas方法总结
Feb 12 Javascript
layui复选框的全选与取消实现方法
Sep 02 Javascript
js 图片懒加载的实现
Oct 21 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 强制下载文件实现代码
2013/10/28 PHP
PHP中文编码小技巧
2014/12/25 PHP
php字符串过滤与替换小结
2015/01/26 PHP
PHP性能分析工具xhprof的安装使用与注意事项
2017/12/19 PHP
关于js类的定义
2011/06/28 Javascript
js FLASH幻灯片字符串中有连接符&的处理方法
2012/03/01 Javascript
几种延迟加载JS代码的方法加快网页的访问速度
2013/10/12 Javascript
jQuery取得设置清空select选择的文本与值
2014/07/08 Javascript
js实现上传图片预览的方法
2015/02/09 Javascript
浅谈下拉菜单中的Option对象
2015/05/10 Javascript
javascript中加var和不加var的区别 你真的懂吗
2016/01/06 Javascript
全面解析JS字符串和正则表达式中的match、replace、exec等函数
2016/07/01 Javascript
js捕捉键盘事件和按键键值的方法
2016/10/10 Javascript
TypeScript学习之强制类型的转换
2016/12/27 Javascript
nodejs服务搭建教程 nodejs访问本地站点文件
2017/04/07 NodeJs
Vue数据绑定简析小结
2019/05/07 Javascript
微信小程序拼接图片链接无底洞深入探究
2019/09/03 Javascript
nuxt框架中对vuex进行模块化设置的实现方法
2019/09/06 Javascript
js中延迟加载和预加载的具体使用
2021/01/14 Javascript
python访问类中docstring注释的实现方法
2015/05/04 Python
详解pandas.DataFrame中删除包涵特定字符串所在的行
2019/04/04 Python
Python 实例方法、类方法、静态方法的区别与作用
2019/08/14 Python
Python守护进程实现过程详解
2020/02/10 Python
澳大利亚时尚前卫设计师珠宝在线:Amber Sceats
2017/10/04 全球购物
如何用SQL语句进行模糊查找
2015/09/25 面试题
信息管理专业推荐信
2013/10/29 职场文书
自主招生自荐信
2013/12/08 职场文书
婚礼答谢宴主持词
2014/03/14 职场文书
班级学习计划书
2014/04/27 职场文书
社区活动策划方案
2014/08/21 职场文书
2014年教师节红领巾广播稿
2014/09/10 职场文书
商务司机岗位职责
2015/04/10 职场文书
2015年保育员个人工作总结
2015/05/13 职场文书
爱国电影观后感
2015/06/19 职场文书
用几道面试题来看JavaScript执行机制
2021/04/30 Javascript
如何将numpy二维数组中的np.nan值替换为指定的值
2021/05/14 Python