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脚本
Dec 03 Javascript
Js 获取HTML DOM节点元素的方法小结
Apr 24 Javascript
javascript appendChild,innerHTML,join性能比较代码
Aug 29 Javascript
JavaScript 格式字符串的应用
Mar 29 Javascript
jquery使用ajax实现微信自动回复插件
Apr 28 Javascript
jQuery添加删除DOM元素方法详解
Jan 18 Javascript
JavaScript必知必会(六) delete in instanceof
Jun 08 Javascript
JS实现的简单图片切换功能示例【测试可用】
Feb 14 Javascript
JS实现仿UC浏览器前进后退效果的实例代码
Jul 17 Javascript
JScript实现地址选择功能
Aug 15 Javascript
微信小程序实现预览图片功能
Oct 22 Javascript
vue实现瀑布流组件滑动加载更多
Mar 10 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代码优化及php相关问题总结
2006/10/09 PHP
Smarty实现页面静态化(生成HTML)的方法
2016/05/23 PHP
在laravel中实现事务回滚的方法
2019/10/10 PHP
tp5.1 框架数据库高级查询技巧实例总结
2020/05/25 PHP
可以显示单图片,多图片ajax请求的ThickBox3.1类下载
2007/12/23 Javascript
js判断设备是否为PC并调整图片大小
2014/02/12 Javascript
js显示当前日期时间和星期几
2015/10/22 Javascript
jquery中checkbox使用方法简单实例演示
2015/11/24 Javascript
基于KO+BootStrap+MVC实现的分页控件代码分享
2016/11/07 Javascript
深入理解JS继承和原型链的问题
2016/12/17 Javascript
Vue2.0基于vue-cli+webpack Vuex的用法(实例讲解)
2017/09/15 Javascript
vue.js模仿京东省市区三级联动的选择组件实例代码
2017/11/22 Javascript
vue项目中v-model父子组件通信的实现详解
2017/12/10 Javascript
vue 组件高级用法实例详解
2018/04/11 Javascript
详解开发react应用最好用的脚手架 create-react-app
2018/04/24 Javascript
Ant Design的Table组件去除
2020/10/24 Javascript
python复制文件的方法实例详解
2015/05/22 Python
Python切换pip安装源的方法详解
2016/11/18 Python
django框架如何集成celery进行开发
2017/05/24 Python
Django实现快速分页的方法实例
2017/10/22 Python
Python探索之URL Dispatcher实例详解
2017/10/28 Python
Python插件virtualenv搭建虚拟环境
2017/11/20 Python
tensorflow中next_batch的具体使用
2018/02/02 Python
浅谈python日志的配置文件路径问题
2018/04/28 Python
python实现PDF中表格转化为Excel的方法
2020/06/16 Python
CSS3选择器新增问题的实现
2021/01/21 HTML / CSS
使用HTML5 Canvas API控制字体的显示与渲染的方法
2016/03/24 HTML / CSS
戴森英国官网:Dyson英国
2019/05/07 全球购物
数百万免费的图形资源:Freepik
2020/09/21 全球购物
劳资员岗位职责
2013/11/11 职场文书
教职工代表大会主持词
2014/04/01 职场文书
商务专员岗位职责范本
2014/06/29 职场文书
党委书记个人对照检查材料
2014/09/15 职场文书
后进生评语大全
2015/01/04 职场文书
2015年客服工作总结范文
2015/04/02 职场文书
地球上的星星观后感
2015/06/02 职场文书