JavaScript高级 - 纯js实现文件上传大文件切片上传断点续传(客户端)

本文介绍了如何使用JavaScript在客户端实现文件上传,包括单文件、多文件上传,以及大文件的切片上传和断点续传功能。详细讲述了使用axios进行二次封装,以及结合spark-md5生成文件hash码来实现断点续传。文章提供了各功能模块的实现步骤和关键代码,涵盖了文件选择、Base64上传、FormData上传、拖拽上传等不同上传方式。
摘要由CSDN通过智能技术生成


前言

一、环境准备及依赖库

  • axios v0.21.1: 用于调用服务端接口发送服务端请求
  • spark-md5 v3.0.1: 用于根据文件内容生成hash码
  • qs v6.9.6:用于将application/x-www-form-urlencoded格式从参数解析为a=x&b=y的格式

二、项目结构

web 项目根目录

  • scripts 存放js脚本目录
    • axios.min.js axios库(第三方)
    • qs.js qs库(第三方)
    • spark-md5.min.js spark-md5库(第三方)
    • axios2.js axios二次封装库(自定义)、
    • upload.js 上传文件功能代码(自定义)
  • css 样式文件目录
    • upload.css 页面样式
  • index.html 文件上传html页面

三、 功能实现

  • 结合上面的截图,将分为5个模块进行讲解,所有模块用到的上传控件都是html原生的类型为file的input控件。
  • 为了页面的美观,我们将input隐藏起来,并用普通按钮替代,当点击按钮时触发input的click事件。
  • 另外可以再额外加一些进度显示,图片缩略图显示,文件名称显示等。
  • 关于HTML和css部分不再过多说明,下面将分模块进行js部分重点讲解,每个模块都用闭包函数包裹,避免变量冲突

1、axios二次封装

在每个功能模块中,我们都将通过使用axios向服务端发送请求,这时我们就需要对axios做一些特殊处理,也就是二次封装

  • 创建axios对象,避免不同场景配置冲突
  • 设置baseURL
  • 设置默认Content-Type 为 multipart/form-data
  • 在transformRequest中判断Content-Type,如果是application/x-www-form-urlencoded 则利用qs库对参数进行格式化
//axios.js axios二次封装
let request = axios.create();
request.defaults.baseURL = 'http://127.0.0.1:3000';
request.defaults.headers['Content-Type'] = 'mutipart/form-data';
request.defaults.transformRequest = (data, headers) => {
   
    let contentType = headers['Content-Type'];
    if (contentType === 'application/x-www-form-urlencoded') return Qs.stringify(data);
    return data;
}

request.interceptors.response.use(response => {
   
    return response.data;
});

2、 单文件上传FROM-DATA,先选文件再上传

在这里插入图片描述

  • 简单步骤分析:
  • 首先应该先获取到需要用到的页面元素:上传控件input,选择按钮,上传按钮,缩略图展示,文件展示,进度条展示
  • 绑定选择按钮的click事件并在click事件中触发上传控件input的click事件
  • 绑定上传控件input的change事件,在该事件中获取已选择的文件
  • 绑定上传按钮的click事件,在该事件中组合参数并发送post请求调用服务端API实现文件上传
  • 文件上传的关键代码就是发送请求前的参数拼接部分
    • 这里我们利用js内置的FromData类将文件作为参数传输
    • new FormData().append(“file”, file);
  • 代码实现
//upload.js 单文件上传form-data
(function () {
   
    let upload1 = document.querySelector("#upload1"),
        upload_inp = upload1.querySelector('.upload-inp'),
        upload_select = upload1.querySelector('.upload-btn.select'),
        upload_upload = upload1.querySelector('.upload-btn.upload'),
        sel_files = upload1.querySelector('.files'),
        file1 = upload1.querySelector('.abbr'),
        cur_pro = upload1.querySelector('.cur-pro'),
        pro_val = upload1.querySelector('.pro-val'),
        progress = upload1.querySelector('.progress'),
        _file;

    upload_select.addEventListener('click', () => {
   
        upload_inp.click();
    });
    upload_inp.addEventListener('change', function () {
   
        let file = this.files[0];
        _file = file;
        sel_files.innerHTML = file.name;
        progress.style.display = 'inline-block';
        pro_val.innerHTML = '';
    })

    upload_upload.addEventListener('click', function () {
   
        let formData = new FormData();
        formData.append('file', _file);
        formData.append('filename', _file.name);
        request.post('/upload_single_file', formData, {
   
            onUploadProgress: function (ev) {
   
                let pro = ((ev.loaded / ev.total) * 100).toFixed(0) + '%';
                cur_pro.style.width = pro;
                pro_val.innerHTML = pro;
            }
        }).then(res => {
   
            console.log(res);
            file1.src = `http://${
     res.serverPath}`;
            file1.style.display = 'block';
        }).catch(err => {
   
            console.log(err);
        });
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值