【前端】-【前端文件操作与文件上传】-【前端接受后端传输文件指南】

news2025/1/15 13:12:53

目录

  • 前端文件操作与文件上传
  • 前端接受后端传输文件指南

前端文件操作与文件上传

一、前端文件上传有两种思路:

  1. 二进制blob传输:典型案例是formData传输,相当于用formData搭载二进制的blob传给后端
  2. base64传输:转为base64传输,后端再将base64转回来。简便、耗时

二、与文件相关的对象

  1. files:通过input标签读过来的文件对象,是blob的子类。
  2. blob:不可变的二进制内容,包含很多操作方法,切片上传、断点续传都是基于blob的
  3. formData:用于后端传输的对象。files是一个前端的对象,不能直接传给后端,所以我们需要一个前后端都认可的载体来传递文件,这个载体就是formData。formData就像一辆汽车用来搭载files,这样才能让文件以二进制的形式传到后端
  4. fileReader:多用于把文件读取为某种形式(如base64、text文件)直接传给后端

三、file参数、blob切割文件、FileReader将文件转成base64,浓缩图/文本预览:

<template>
  <div>
    <input type="file" name="file" @change="fileChange" />
    <!-- 缩略图,文本预览 -->
    <img style="width:200px;" :src="imgbase64" />
    <button @click="submit">提交</button>
  </div>
</template>

<script>
import axios from "axios"
import { fstat } from "fs";
let _fileObj;
export default {
  name: 'HelloWorld',
  data() {
    return {
      imgbase64: "",
    }
  },
  methods: {
    fileChange(e) {
       let file = e.target.files[0]// files是个数组
       _fileObj = file;
       // file常用属性:size(大小)、type(类型)、name(文件名)
      if (file.size > 10 * 24 * 24) {
        alert("文件不能大于十兆")
      }
      if (file.type !== 'video/mp4') {
        alert("必须是mp4")
      }
      // 使用blob的slice方法可以切割文件
      let _sliceBlob = new Blob([file]).slice(0, 5000);// 切割二进制的0-5000位
      // 将切割后的Blob对象转成File对象(第二个参数是文件名),之后就可以上传切割后的File对象
      let _sliceFile = new File([_sliceBlob], "test.png");
      
      //将File对象或者Blob对象转成base64或text
      let fr = new FileReader();
      fr.readAsDataURL(_sliceFile);// readAsDataURL是转成base64的方法
      let self = this;
      fr.onload = function () {
        // base64是异步的转换,通过onload方法获得转换结果
        self.imgbase64 = fr.result// 直接将转换结果赋值给img的src,设置src的大小即可获得浓缩图
        console.log(fr.result)// 打印结果见下图一
      }
    },
    async submit() {
    // 这部分的代码后面讲
    	let _formData = new FormData();
        _formData.append("user", "asdasd");
        _formData.append("file", _fileObj)
        axios.post("/xx", _formData);
    }
    }
  }
}
</script>

图一:上传结果打印
四、formData:不仅可以搭载文件,还可以搭载文字、input的其他输入

<form action="xxx" method="post">默认情况下提交为query参数</from>
<form action="xxx" method="post" enctype="multipart/form-data">enctype指定提交为formData</from>

五、文件上传:将blob转成FormData上传

async submit() {
	let _formData = new FormData();
    _formData.append("user", "asdasd");
    _formData.append("file", _fileObj)
    axios.post("/xx", _formData);
}

通过查看网络可以发现:

  1. 上传内容:
    请添加图片描述
  2. 请求头content-Type指定了传输内容为form-data,且boundary指定了分割符
    请添加图片描述
  3. 分隔了两个内容(下面还有一个分割线,即以分割线结尾)
    请添加图片描述
    六、转换关系
    请添加图片描述
  4. 我们直接拿到的是file对象,file对象可以转换成Blob对象,Blob对象也可以转成file对象
  5. file、blob都可以根据FileReader读成base64或text文本
  6. 通过接口传输给后端时,只能传输base64、text文本、formData,所以,如果不把file、blob通过FileReader读成base64或text文本,那么就需要把file或者blob append到formData才能通过接口传输

七、具体功能

  1. 单文件上传(详见前述代码)
  2. 多文件上传:
<template>
  <div>
    <input type="file" name="file" @change="fileChange" multiple />
    <span v-for="item in imgList">{{ item.name }}</span>
    <button @click="submit">提交</button>
  </div>
</template>

<script>
import axios from "axios"
import { fstat } from "fs";
let _fileObj;
export default {
  name: 'HelloWorld',
  data() {
    return {
      imgList: [],
    }
  },
  methods: {
    fileChange(e) {
      //多文件上传
      // multiple的多文件上传其实很不友好,需要用户在选择文件时按住ctrl多选,否则就会变成单选
      // 所以使用imgList数组将用户每次选择的内容都push进去
      if (e.target.files.length > 1) {
        
        this.imgList.concat(e.target.files)
      } else {
        this.imgList.push(e.target.files[0]);
      }
      //切片上传
      _fileObj = e.target.files[0]
    },
    async submit() {
      // 遍历,一个一个上传
      this.imgList.forEach((item) => {
        let _formData = new FormData();
        _formData.append(item.name + "file", item)
        axios.post("/xx", _formData);
      })
    }
  }
}
</script>
  1. 切片上传
<template>
  <div>

    <input type="file" name="file" @change="fileChange" multiple />
    <div>{{ precent }}%</div>
    <button @click="submit">提交</button>
  </div>
</template>

<script>
import axios from "axios"
import { fstat } from "fs";
let _fileObj;
export default {
  name: 'HelloWorld',
  data() {
    return {
      precent: 0
    }
  },
  methods: {
    fileChange(e) {
      //切片上传,在上传的时候进行切片,文件改变时只赋值
      _fileObj = e.target.files[0]
    },
    async submit() {
      let size = 2 * 1024 * 1024;// 每次切片的大小,片为2m
      let fileSize = _fileObj.size;
      let current = 0;// 当前已经传了多少
      // 断点续传,永久记录中断的地方,下次上传时直接从断点开始传
      //localStorage.setItem(_fileObj.name, current);
      while (current < fileSize) {
        let _formData = new FormData();
        _formData.append(_fileObj.name, _fileObj.slice(current, current + size))
        await axios.post("http://localhost:4000/upload",_formData)
        // 进度条可以用axios的onUploadProgress方法,且发送切片时可以并行发送请求,后续可以自行优化
        this.precent = Math.min((current / fileSize) * 100, 100)
        current += size;
      }
    }
  }
}
</script>

File System Access API 允许直接读取、写入或保存对用户设备上的文件和文件夹的更改。从 Chrome 86 开始支持 File System Access API,目前只有基于 Chromium 系列的浏览器全面支持,Safari 部分支持(支持读取,不支持写入和保存),而 Firefox 未支持。

前端接受后端传输文件指南

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1653967.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【linux kernel】linux内核hid触摸源码hid-multitouch.c剖析

文章目录 一、内核中通用hid触摸驱动二、probe过程剖析(1)hid_parse()函数(2)hid_hw_start()函数(3)hid_connect()函数三、hid-multitouch.c应用场景一、内核中通用hid触摸驱动 在linux内核中,为HID触摸面板实现了一个通用的驱动程序,位于/drivers/hid/hid-multitouch.c文件…

连续活跃天数统计

连续活跃天数统计 需求说明 什么是连续出现&#xff1f; 假设有如下日期信息&#xff1a; 20230401,20230402,20230403,20230405,20230406,20230407,20230410,20230411 则&#xff1a; 20230401-20230403 为一次连续出现&#xff0c;连续出现天数为 3 20230405-20230407 为一次…

【Qt QML】ComboBox组件

ComboBox 是一个组合的按钮和弹出列表。它提供了一种以最小的屏幕空间呈现选项列表给用户的方式。ComboBox 使用数据模型填充。数据模型通常是一个 JavaScript 数组、一个 ListModel 或一个整数&#xff0c;但也支持其他类型的数据模型。 下面是一个简单的使用方式。 import …

关于Anaconda常用的命令

常用命令 查看当前环境下的环境&#xff1a;conda env list查看当前conda的版本&#xff1b;conda --version conda create -n your_env_name pythonX.X&#xff08;2.7、3.6等)命令创建python版本为X.X。名字为your_env_name的虚拟环境。your_env_name文件可以在Anaconda安装…

专题五_位运算(3)

目录 137. 只出现一次的数字 II 解析 题解 面试题 17.19. 消失的两个数字 解析 题解 137. 只出现一次的数字 II 137. 只出现一次的数字 II - 力扣&#xff08;LeetCode&#xff09; 解析 注意这里指的是比特位上的01来进行统计的 题解 class Solution { public:int sin…

二叉排序树(二叉搜索树)BST增删改查操作

一、定义 二叉搜索树&#xff08;Binary Search Tree&#xff0c;BST&#xff09;是一种常用的二叉树数据结构&#xff0c;具有以下特点&#xff1a; 1. **排序性质**&#xff1a;对于树中的每个节点&#xff0c;其左子树中的所有节点值都小于该节点的值&#xff0c;而右子树…

类和对象(中篇)(未完结)

文章目录 类的6个默认成员函数构造函数析构函数 类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 class Date {};空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 默…

《QT实用小工具·六十一》带动画的三角形指示箭头

1、概述 源码放在文章末尾 该项目实现了一个带动画效果的三角形指示箭头&#xff0c;项目demo演示如下所示&#xff1a; 用法 interestingindicate.h interestingindicate.cpp 放到工程中&#xff0c;直接使用即可。 注意&#xff1a;建议绝对布局&#xff0c;手动指定 wid…

分红76.39亿,分红率再创新高,成长活力无限的伊利带来丰厚回报

伊利47万股东&#xff0c;又等来了一个好消息。 4月29日&#xff0c;伊利股份发布2023年报&#xff0c;实现营业总收入1261.79亿元&#xff0c;归母净利润104.29亿元&#xff0c;双创历史新高&#xff0c;实现连续31年稳健增长。 在递交亮眼成绩单的同时&#xff0c;乳业巨头伊…

Linux系统编程--网络编程

一、OSI网络七层模型 OSI模型将整个网络通信过程分解为七个层次&#xff0c;每个层次都为网络通信提供了特定的功能。以下是OSI模型的七个层次&#xff0c;从上到下依次是&#xff1a; 应用层&#xff08;Application Layer&#xff09;&#xff1a;为应用软件提供网络服务&am…

MySQL部署系列-centos离线安装MySQL

MySQL部署系列-centos离线安装MySQL 文章目录 MySQL部署系列-centos离线安装MySQL1. 查看是否已经安装 Mysql3. 下载官方 Mysql 包3. 下载之后上传到服务器4. 创建用户组5. 创建数据目录并赋予权限6. 修改配置文件 vim /etc/my.cnf7. 初始化数据库(数据库安装)8. 加入到系统服务…

多个开源的js补环境框架测试

原文链接&#xff1a;https://mp.weixin.qq.com/s/uEMFGpE5bqmTvzSgX2twvA 前言 在做js逆向时肯定会遇到补环境的情况&#xff0c;看到github开源了好几个补环境用的框架&#xff0c;这篇文章做个测试&#xff0c;看看哪个比较好用。 https://github.com/pysunday/sdenvhttp…

word格式技巧

文章目录 论文格式技巧论文交叉引用怎么弄论文的页码怎么弄 论文格式技巧 论文交叉引用怎么弄 1.取消文献原有的编号 2.定义新编号 3.具体编号设置 4.在引用的地方插入&#xff0c;具体引用选项卡–>交叉引用–>选择后插入 2. 4. 论文的页码怎么弄 假设我们有这样一…

探索DeepSeek平台:新一代MoE模型的深度体验

简介 DeepSeek是一个创新的人工智能平台&#xff0c;它最近推出了其最新版本的模型——DeepSeek-V2 MoE&#xff08;Mixture of Experts&#xff09;。这个平台不仅提供了一个交互式的聊天界面&#xff0c;还提供了API接口&#xff0c;让用户可以更深入地体验和利用这一先进的…

scala速通(精简版)

1.变量和常量 var name [:VariableType] value // variable val name [:ConstantType] value // constant1.声明变量时&#xff0c;类型可以省略 2.类型定义后就不能修改言 3.变量声明必须有初始值 4.变量&#xff0c;常量分别用var&#xff0c;val声明修饰 2.标识符命名…

构建自己的docker镜像node.js

学习资源&#xff1a; 构建自己的 Docker 镜像_哔哩哔哩_bilibili 针对其中的一些比较困难的点写篇文章。 以下是对app.js的注释&#xff1a; // 使用 Koa 框架搭建 Node.js 应用的示例代码// 这两行代码引入了 koa 模块&#xff0c;并创建了一个新的 Koa 应用实例&#xf…

vue2项目升级到vue3经历分享4

后端重构&#xff0c;如果接口做好抽象封装&#xff0c;只需要考虑jar之间的兼容性问题&#xff0c;jdk版本不变&#xff0c;基本不用做太大的调整&#xff0c;但是前端就不一样&#xff0c;除了vue框架本身&#xff0c;css的调整&#xff0c;改起来更是让人头疼。前面写了vue2…

如何让vim支持python3

首先删除旧的vim。 sudo apt-get remove vim //输入re按下tab直接显示remove sudo apt-get remove vim-runtime sudo apt-get remove vim -tiny sudo apt-get remove vim-common 然后下载vim8源码&#xff1a; git clone https://github.com/vim/vim.git 进行编译安装…

一键剪辑1000条视频的矩阵系统小魔推到底有多牛?

小魔推是一款短视频营销工具&#xff0c;主要针对想做短视频营销的实体商家与企业。通过BGC、PGC、UGC流量的打造&#xff0c;帮助更多实体行业实现流量裂变与转化。通过小魔推不需要做额外的拍摄剪辑创作动作&#xff0c;只需要通过小魔推宣传码&#xff0c;就能一键发布带有门…

20240508请问GTX2080TI的300和300A核心的差异?

20240508请问GTX2080TI的300和300A核心的差异&#xff1f; 在拼多多/淘宝上&#xff0c;GTX2080TI的300A核心的会比300核心的贵100&#xffe5;左右。 但是怎么区分呢&#xff1f; 300a核心和300请问怎么区分呢&#xff1f;[嘻嘻] devicr ID diviceid 1e07是300a 1e04是300 Gp…