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 相关文章推荐
浅析Prototype的模板类 Template
Dec 07 Javascript
document.getElementBy(&quot;id&quot;)与$(&quot;#id&quot;)有什么区别
Sep 22 Javascript
javascript动态添加、修改、删除对象的属性与方法详解
Jan 27 Javascript
node.js中的fs.readFile方法使用说明
Dec 15 Javascript
微信JSSDK上传图片
Aug 23 Javascript
jQuery实现只允许输入数字和小数点的方法
Mar 02 Javascript
Javascript动画效果(3)
Oct 11 Javascript
jquery点击展示与隐藏更多内容
Dec 03 Javascript
jQuery实现的手风琴侧边菜单效果
Mar 29 jQuery
深入理解vuex2.0 之 modules
Nov 20 Javascript
layer.confirm取消按钮绑定事件的方法
Aug 17 Javascript
微信小程序实现翻牌抽奖动画
Sep 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
ThinkPHP表单自动提交验证实例教程
2014/07/18 PHP
php+mysqli使用面向对象方式查询数据库实例
2015/01/29 PHP
php 利用socket发送HTTP请求(GET,POST)
2015/08/24 PHP
PHP连接数据库实现注册页面的增删改查操作
2016/03/27 PHP
php实现微信支付之企业付款
2018/05/30 PHP
打开超链需要“确认”对话框的方法
2007/03/08 Javascript
js open() 与showModalDialog()方法使用介绍
2013/09/10 Javascript
JS控制网页动态生成任意行列数表格的方法
2015/03/09 Javascript
jQuery在页面加载时动态修改图片尺寸的方法
2015/03/20 Javascript
js+html5绘制图片到canvas的方法
2015/06/05 Javascript
js实现a标签超链接提交form表单的方法
2015/06/24 Javascript
JS实现的新浪微博大厅文字内容滚动效果代码
2015/11/05 Javascript
BootStrap中Datepicker控件带中文的js文件
2016/08/10 Javascript
微信页面倒计时代码(解决safari不兼容date的问题)
2016/12/13 Javascript
JavaScript触发onScroll事件的函数节流详解
2016/12/14 Javascript
vue2.0+ 从插件开发到npm发布的示例代码
2018/04/28 Javascript
深入理解 Koa 框架中间件原理
2018/10/18 Javascript
JS apply用法总结和使用场景实例分析
2020/03/14 Javascript
在Vue 中实现循环渲染多个相同echarts图表
2020/07/20 Javascript
Vue用mixin合并重复代码的实现
2020/11/27 Vue.js
[33:23]Secret vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
[01:01:52]完美世界DOTA2联赛PWL S2 GXR vs Magma 第二场 11.25
2020/11/26 DOTA
python抓取需要扫微信登陆页面
2019/04/29 Python
pyQT5 实现窗体之间传值的示例
2019/06/20 Python
Python音频操作工具PyAudio上手教程详解
2019/06/26 Python
为什么说python更适合树莓派编程
2020/07/20 Python
Pytorch实验常用代码段汇总
2020/11/19 Python
HTML5如何实现元素拖拽
2016/03/11 HTML / CSS
萌新HTML5 入门指南(二)
2020/11/09 HTML / CSS
IdealFit官方网站:女性蛋白质、补充剂和运动服装
2019/03/24 全球购物
英国婴儿产品专家:Samuel Johnston
2020/04/20 全球购物
税务专业毕业生自荐信
2013/11/10 职场文书
财务总监岗位职责
2014/03/07 职场文书
民主生活会对照检查材料(统计局)
2014/09/21 职场文书
优秀党支部申报材料
2014/12/24 职场文书
街道社区活动报告
2015/02/05 职场文书