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获取上传文件大小示例代码
Apr 10 Javascript
jQuery中data()方法用法实例
Dec 27 Javascript
浅析jQuery Mobile的初始化事件
Dec 03 Javascript
js下将金额数字每三位一逗号分隔
Feb 19 Javascript
解析浏览器端的AJAX缓存机制
Jun 21 Javascript
Angularjs 实现分页功能及示例代码
Sep 14 Javascript
bootstrap table复杂操作代码
Nov 01 Javascript
JQuery 动态生成Table表格实例代码
Dec 02 Javascript
JavaScript中三个等号和两个等号你了解多少
Jul 04 Javascript
微信小程序 跳转传递数据的实例
Jul 06 Javascript
js判断密码强度的方法
Mar 18 Javascript
详解vue-flickity的fullScreen功能实现
Apr 07 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连mysql和oracle数据库性能比较
2006/10/09 PHP
PHP 杂谈《重构-改善既有代码的设计》之一 重新组织你的函数
2012/04/09 PHP
php的ddos攻击解决方法
2015/01/08 PHP
php根据用户语言跳转相应网页
2015/11/04 PHP
PHP面向对象之工作单元(实例讲解)
2017/06/26 PHP
PHP实现八皇后算法
2019/05/06 PHP
javasciprt下jquery函数$.post执行无响应的解决方法
2014/03/13 Javascript
Jquery常用的方法汇总
2015/09/01 Javascript
利用Node.JS实现邮件发送功能
2016/10/21 Javascript
Jquery实现跨域异步上传文件总结
2017/02/03 Javascript
js实现一个简单的数字时钟效果
2017/03/29 Javascript
jQuery源码解读之extend()与工具方法、实例方法详解
2017/03/30 jQuery
[48:02]Ti4循环赛第三日 VG vs Liquid和NEWBEE vs DK
2014/07/12 DOTA
Python urlopen()和urlretrieve()用法解析
2020/01/07 Python
python读取raw binary图片并提取统计信息的实例
2020/01/09 Python
Pytest参数化parametrize使用代码实例
2020/02/22 Python
使用Python实现将多表分批次从数据库导出到Excel
2020/05/15 Python
深入理解Python变量的数据类型和存储
2021/02/01 Python
HTML5边玩边学(2)基础绘图实现方法
2010/09/21 HTML / CSS
美国最大的香水连锁店官网:Perfumania
2016/08/15 全球购物
以工厂直接定价的传奇性能:Ben Hogan Golf
2019/01/04 全球购物
德国在线购买葡萄酒网站:Geile Weine
2019/09/24 全球购物
沙特阿拉伯排名第一的在线时尚购物应用程序:1Zillion
2020/08/08 全球购物
你所知道的集合类都有哪些?主要方法?
2012/12/31 面试题
介绍JAVA 中的Collection FrameWork(及如何写自己的数据结构)
2014/10/31 面试题
后勤人员岗位职责
2013/12/17 职场文书
制药工程专业毕业生推荐信
2013/12/24 职场文书
药剂专业学生求职信范文
2013/12/28 职场文书
竞聘演讲稿范文
2014/01/12 职场文书
军校大学生个人的自我评价
2014/02/17 职场文书
广告学专业毕业生自荐信
2014/05/28 职场文书
群众路线剖析材料范文
2014/10/09 职场文书
2015年大学学生会工作总结
2015/05/13 职场文书
如何使用JavaScript策略模式校验表单
2021/04/29 Javascript
MySQL 不等于的三种使用及区别
2021/06/03 MySQL
Spring Boot项目传参校验的最佳实践指南
2022/04/05 Java/Android