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 相关文章推荐
javascript CSS画图之基础篇
Jul 29 Javascript
JavaScript 布尔操作符解析  &amp;&amp; || !
Aug 10 Javascript
CSS(js)限制页面显示的文本字符长度
Dec 27 Javascript
extjs两个tbar问题探讨
Aug 08 Javascript
json的定义、标准格式及json字符串检验
May 11 Javascript
JavaScript隐式类型转换
Mar 15 Javascript
jQuery Easyui使用(一)之可折叠面板的布局手风琴菜单
Aug 17 Javascript
深入理解jQuery()方法的构建原理
Dec 05 Javascript
使用BootStrap建立响应式网页——通栏轮播图(carousel)
Dec 21 Javascript
Bootstrap面板学习使用
Feb 09 Javascript
Angular2关于@angular/cli默认端口号配置的问题
Jul 15 Javascript
vue实现div单选多选功能
Jul 16 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
MySQL GBK→UTF-8编码转换
2007/05/24 PHP
PHP容易被忽略而出错陷阱 数字与字符串比较
2011/11/10 PHP
ThinkPHP让分页保持搜索状态的方法
2014/07/02 PHP
php生成随机颜色的方法
2014/11/13 PHP
PHP截取指定图片大小的方法
2014/12/10 PHP
ThinkPHP内置jsonRPC的缺陷分析
2014/12/18 PHP
PHP7如何开启Opcode打造强悍性能详解
2018/05/11 PHP
javaScript - 如何引入js代码
2021/03/09 Javascript
js调用浏览器打印模块实现点击按钮触发自定义函数
2014/03/21 Javascript
jQuery使用append在html元素后同时添加多项内容的方法
2015/03/26 Javascript
简述JavaScript中正则表达式的使用方法
2015/06/15 Javascript
jQuery实现查找链接文字替换属性的方法
2016/06/27 Javascript
Angular2 (RC4) 路由与导航详解
2016/09/21 Javascript
vue中路由参数传递可能会遇到的坑
2017/12/07 Javascript
ExtJs整合Echarts的示例代码
2018/02/27 Javascript
vue中实现移动端的scroll滚动方法
2018/03/03 Javascript
浅谈webpack-dev-server的配置和使用
2018/05/17 Javascript
webpack 从指定入口文件中提取公共文件的方法
2018/11/13 Javascript
独立部署小程序基于nodejs的服务器过程详解
2019/06/24 NodeJs
解决Vue在Tomcat8下部署页面不加载的问题
2019/11/12 Javascript
vue中实现动态生成二维码的方法
2020/02/21 Javascript
Python抓取百度查询结果的方法
2015/07/08 Python
Python Unittest自动化单元测试框架详解
2018/04/04 Python
Python Selenium 之关闭窗口close与quit的方法
2019/02/13 Python
Python嵌套式数据结构实例浅析
2019/03/05 Python
CentOS7下安装python3.6.8的教程详解
2020/01/03 Python
Django创建一个后台的基本步骤记录
2020/10/02 Python
python 多线程中join()的作用
2020/10/29 Python
教师现实表现材料
2014/02/14 职场文书
销售个人求职信范文
2014/04/28 职场文书
安全生产目标管理责任书
2014/07/25 职场文书
考试作弊检讨书范文
2015/01/27 职场文书
副总经理岗位职责
2015/02/02 职场文书
浅谈redis缓存在项目中的使用
2021/05/20 Redis
mysql 直接拷贝data 目录下文件还原数据的实现
2021/07/25 MySQL
纯html+css实现奥运五环的示例代码
2021/08/02 HTML / CSS