axios上传图片,koa2接收保存上传的图片,lrz在上传前压缩图片

栏目: Node.js · 发布时间: 5年前

内容简介:初始化koa2项目这里不多说,github上有个开源的koa-generator项目,安装运行一下初始化命令即可,readme上有详细介绍不过有点要提一下,koa-generator脚手架里使用的是koa-bodyparser,这货不支持上传文件的解析,当初折腾这个纠结了一阵这里使用koa2搭建服务端,使用koa-body,版本是

后台接收图片

初始化koa2项目这里不多说,github上有个开源的koa-generator项目,安装运行一下初始化命令即可,readme上有详细介绍

不过有点要提一下,koa-generator脚手架里使用的是koa-bodyparser,这货不支持上传文件的解析,当初折腾这个纠结了一阵

这里使用koa2搭建服务端,使用koa-body,版本是 "koa-body": "^4.0.6",

安装 yarn add koa-body

app.js 里要修改一下,搜索一下 koa-bodyparser 把它相关的代码都去掉,然后加上下面代码

const koaBody = require('koa-body');

app.use(koaBody({
  multipart: true,
  formidable: {
    maxFileSize: 200 * 1024 * 1024    // 设置上传文件大小最大限制,默认2M
  }
}));

开发上传路由处理上传文件操作

首先安装两个依赖, mkdirp node-uuid 前一个是创建多层文件夹的,后面是生成uuid作为文件名的,你如果要手动指定文件名,也可以不安装这个

yarn add mkdirp node-uuid
const mkdirp = require('mkdirp');
const uuid = require('node-uuid');
const path = require('path')
const fs = require('fs')

// 上传文件
exports.upload = async ctx => {
  // 从请求参数里拿文件名,没有获取到就使用uuid生成一串uuid作为文件名
  const filename = ctx.request.body.filename || uuid.v4();
  const file = ctx.request.files.file;    // 获取上传文件
  if (file) {
    const reader = fs.createReadStream(file.path);    // 创建可读流
    const ext = file.name.split('.').pop();        // 获取上传文件扩展名
    // 创建文件夹
    const uploadPath = "/Users/hh/Desktop/upload"; // 这是我测试的路径
    const flag = fs.existsSync(uploadPath); // 判断文件夹是否存在
    // 同步创建多级文件夹
    if (!flag) mkdirp.sync(uploadPath);
    const upStream = fs.createWriteStream(`${uploadPath}/${filename}.${ext}`); // 创建可写流
    await reader.pipe(upStream);    // 可读流通过管道写入可写流
    ctx.body = {"code": 200, "description": "SUCCESS"};
  } else {
    ctx.body = {"code": 201, "description": "没有选择图片"};
  }
}

这样写完还有个问题,跨域,不过对于koa来说,没有一个中间件解决不了的,继续安装依赖

yarn add koa2-cors

在app.js 里做如下配置

app.use(cors({
  origin: 'http://localhost:3001', // 这个域名就是上传页面所部署的服务的域名,根据自己的场景做相应的调整
  // exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
  // maxAge: 5,
  // credentials: true,
  allowMethods: ['POST'],
  allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
}));

前端axios上传图片

之所以用它,是因为它默认有上传进度,瞎扯的,其实是因为它流行,网上流行啥,咱就用啥 :joy

实现逻辑说一下,有两种方式

  1. 直接给一个 input[type=”file”] 的html组件,点击后使用js监听 onchange 方法,然后在onchange方法里添加上传代码
  2. 为了美观,可以给一个按钮和一个input[type=”file”]不过这个file输入框要隐藏,当点击这个按钮的时候,使用js去手动的调用file输入框的点击事件,相当于鼠标点击了,后面都一样监听onchange事件即可

我这采用第一种方法

<input type="file" id="imageFile" onchange="uploadImage()" style="display: none;">

<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script>
function uploadImage() {
  var fd = new FormData();
  fd.append("image", document.getElementById("imageFile").files[0]);
  // 如果还想传一些参数,可以继续使用fd.append("filename", "自定义文件名");
  axios({
    method: 'POST',
    url: 'http://localhost:3000/upload',
    data: fd,
    headers: {
      'Content-Type': 'multipart/form-data'
    },
    // 添加上传进度
    onUploadProgress: function(e) {
      var percentage = Math.round((e.loaded * 100) / e.total) || 0;
      if (percentage < 100) {
        console.log(percentage + '%');  // 上传进度
      }
    }
  }).then(resp => {
      console.log(resp.data);
  }).catch(err => console.log(err));
}
</script>

上传图片怎么能少了压缩呢

昨天网上搜了一下,发现一个很好用的工具 lrz

引入js

# 如果你是前端项目,直接安装
yarn add lrz
# 如果你想直接引入js,我在cdnjs上没有找这个,所以自己安装一下吧
bower install lrz
# 然后再引入

使用

<script>
function uploadImage() {
  lrz(document.getElementById("imageFile").files[0])
    .then(rst => {
      var fd = new FormData();
      fd.append("image", document.getElementById("imageFile").files[0]);
      // 如果还想传一些参数,可以继续使用fd.append("filename", "自定义文件名");
      axios({
        method: 'POST',
        url: 'http://localhost:3000/upload',
        data: fd,
        headers: {
          'Content-Type': 'multipart/form-data'
        },
        // 添加上传进度
        onUploadProgress: function(e) {
          var percentage = Math.round((e.loaded * 100) / e.total) || 0;
          if (percentage < 100) {
            console.log(percentage + '%');  // 上传进度
          }
        }
      }).then(resp => {
        console.log(resp.data);
      }).catch(err => console.log(err));
    }).catch(function (err) {
      // 处理失败会执行
      console.log("压缩图片失败!");
      Toast.hide();
    }).always(function () {
      // 不管是成功失败,都会执行
    });
}
</script>

实测,一张8M+图片,压缩上传后,图片大小不到2M,还很清晰

参考

原文链接:


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大数据预测

大数据预测

【美】埃里克·西格尔 / 周昕 / 中信出版社 / 2014-3 / 58.00

360公司董事长周鸿祎、《罗辑思维》主讲人罗振宇郑重推荐 2020年的一天,在你驱车前往公司的路上,导航系统通过预测交通流量,会自动帮你选择一条最合适的交通路线;车内推荐系统会根据你的饮食习惯预测你可能会喜欢吃什么,并推荐沿途的早餐店;你的电子社交助理已经为你自动选择了你可能感兴趣的社交网信息;当车内系统预测到你驾车有些分心时,座椅会自动震动进行提醒…… 以上这些情景不是科幻大片独有的......一起来看看 《大数据预测》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试