下面要做一个ajax上传文件显示进度的操作,文末有演示地址
ajax上传文件显示进度_ajax

 


这里先上代码:

1、前端代码

  upload.html

  

2、后端接口(nodejs)

  app.js

   const express = require('express');    const upload = require('multer')({ dest: 'uploads/' });    const path = require('path');    const fs = require('fs');    const port = 8088;
    
    let  app = express();
    
    app.set('port', port);    // index.html, index.js放在static文件夹中
    app.use(express.static(path.join(__dirname, 'static')));    
    // app.get('/', (req, res) => {    //   res.redirect('upload2.html');    // });    
    // 路由/ajax-upload 就回渲染 upload.html 页面
    app.get('/ajax-upload', function(req, res){  
      res.sendFile('upload.html', { root: __dirname });  
    });  
    app.post('/upload', upload.single('test-upload'), (req, res) => {      // 没有附带文件
      if (!req.file) {
        res.json({ ok: false });        return;
      }// 重命名文件
      let oldPath = path.join(__dirname, req.file.path);
      let newPath = path.join(__dirname, 'uploads/' + req.file.originalname);
      fs.rename(oldPath, newPath, (err) => {        if (err) {
          res.json({ ok: false });
          console.log(err);
        } else {
          res.json({ ok: true });
        }
      });
    });    // 这里还没有做上传取消 删除文件的操作
    app.get('/abort', upload.single('test-upload'), (req, res)=>{
      console.log(req, 'abort') // 删除刚才上传的文件    })
    
    app.listen(port, () => {
      console.log("[Server] localhost:" + port);
    });

 

注:接口使用

  • 环境:nodejs
  • 项目结构 
    • app.js
    • upload.html
    • uploads
    • static(图片如下) 
  • 框架包express: npm install express –save
  • 上传包multer :npm install multer –save
  • 启动: node app.js

ajax上传文件显示进度_ajax_02

以上代码可以直接复制运行:

3、解释

3.1.前端

上传简述: 前端的选择文件,掉后端上传接口,利用ajax技术将文件上传的服务器。前端要知道后端是否上传成功或者状态,就得需要后端返回给我们的状态,最简单的就是上传成功或者失败,再者需要知道进度的就要利用xhr 的进程方法了。
  • ajax 的原理就是利用浏览器的XMLHttRequest 这个对象,因为IE浏览器不是这对象,如果要兼容的话 ,可以封装一个XHR 对象,代码可以看后面的附属部分:
  • XMLHttRequest 对象有多个方法,监控ajax 上传的进度主要利用这些属性,来达到我们的目标
  • 下面是部分属性(方法)介绍,这里是MDN的介绍 xhr 
    • onloadstart 获取开始
    • onprogress 数据传输进行中
    • onabort 获取操作终止
    • onerror 获取失败
    • onload 获取成功
    • ontimeout 获取操作在用户规定的时间内未完成
    • onloadend 获取完成(不论成功与否)

* 对xhr.upload.onprogress的解释

这里监控进度主要看这里的属性值的变化,如下图 
ajax上传文件显示进度_ajax_03
具体的代码片段解释可以查看我上面的代码注释

3.2.后端

这里使用的nodejs的一个接口,之前我的用的是将前端预览图片的base64的字符串传到后端,然后后端解析这个base64的字符串,生成图片,保存在磁盘中,但是会出现问题,进度不太好显示,所以查了相关资料,借用了这里的写法,直接上传文 件;还有一个就是multer包,利用这个进行上传。

这里项目也是一个后端渲染的方式,将页面渲染好,然后发送给前端。

4、附属代码:

4.1.兼容的ajax代码段

function XMLHttpRequest(){    if (typeof XMLHttpRequest != "undefined"){    return new XMLHttpRequest();
    } else if (typeof ActiveXObject != "undefined"){        if (typeof arguments.callee.activeXString != "string"){        var versions = [ "MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",        "MSXML2.XMLHttp"],
        i, len;        for (i=0,len=versions.length; i < len; i++){            try {                new ActiveXObject(versions[i]);
                arguments.callee.activeXString = versions[i];            break;
            } catch (ex){                //跳过            }
        }
    }         return new ActiveXObject(arguments.callee.activeXString);
    } else {        throw new Error("No XHR object available.");
    }
}

 

4.2.nodejs 处理base64字符串

node包:formidable 
imgBase64Arr: 前端传值过来的 base64字符串的多张图片的数组

for(var i = 0;i<imgBase64Arr.length;i++) {    var imgname    = util.randomStr(); // 随机字符串的方法
    imgname    = 'assets/img/'+ imgname + '.png';    var base64     = imgBase64Arr[i].replace(/^data:image\/\w+;base64,/, "");    //去掉图片base64码前面部分data:image/png;base64
    var dataBuffer = new Buffer(base64, 'base64'); //把base64码转成buffer对象,
    console.log('dataBuffer是否是Buffer对象:'+Buffer.isBuffer(dataBuffer));
    fs.writeFile(imgname,dataBuffer,function(err){//用fs写入文件
      if(err){
          console.log(err);
      }else{
          console.log('图片上传成功!');
      }
    })
    newimgarr.push(imgname.replace("assets",""));
}

github地址:https://github.com/adouwt/ajax-upload

 

前端上传这块已经封装了一个基于vue的插件,

GitHub地址:https://github.com/adouwt/vue-upload    

npm 官网上的数据显示已经有一定的下载量,欢迎大家学习使用,有bug,及时告知于我

 https://www.npmjs.com/package/vue-ajax-upload

如有错误,敬请指出!

这里提供了一个demo演示如下, ps:个人服务器存储较小,只是用来展示,后端是个小白,没有做一些文件过滤和后端文件风险校验,大神请绕行哈,还有请手下留情哈!