[后端基础] 文件上传的发展史

这篇具有很好参考价值的文章主要介绍了[后端基础] 文件上传的发展史。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【本文首发于微信公众号: [程序员三木]】

欢迎关注我们的微信公众号,获取更多有关Java和Spring的技术文章和教程。

1. 文件上传的发展史

1.1 form表单同步上传的方式

在ajax请求出来之前,人们都是直接通过form表单提交文件,或者form配合iframe(已废弃)进行文件上传,form配合input进行文件选择。

那么为了了解清楚他们的工作原理,我们有必要来理解一下form以及input元素。

form元素的介绍

<form> 标签用于为用户输入创建 HTML 表单。

表单能够包含 input 元素,比如文本字段、复选框、单选框、提交按钮等等。

表单还可以包含 menus、textarea、fieldset、legend 和 label 元素。

表单用于向服务器传输数据。

form的属性
属性 描述
accept HTML 5 中不支持。
accept-charset 规定服务器可处理的表单数据字符集。
action 规定当提交表单时向何处发送表单数据。
autocomplete 规定是否启用表单的自动完成功能。
enctype 规定在发送表单数据之前如何对其进行编码。
method 规定用于发送 form-data 的 HTTP 方法。
name 规定表单的名称。
novalidate 如果使用该属性,则提交表单时不进行验证。
rel 规定链接资源和当前文档之间的关系。
target 规定在何处打开 action URL。
说明

enctype 属性可能的值:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

input元素的介绍

使用 type="file"input元素使得用户可以选择一个或多个元素以提交表单的方式上传到服务器上,或者通过 Javascript 的 File API 对文件进行操作。

input 的属性:
属性 描述
accept 规定通过文件上传来提交的文件的类型。 (只针对type=“file”)
align HTML5已废弃,不赞成使用。规定图像输入的对齐方式。 (只针对type=“image”)
alt 定义图像输入的替代文本。 (只针对type=“image”)
autocomplete autocomplete 属性规定 元素输入字段是否应该启用自动完成功能。
autofocus 属性规定当页面加载时 元素应该自动获得焦点。
checked checked 属性规定在页面加载时应该被预先选定的 元素。 (只针对 type=“checkbox” 或者 type=“radio”)
disabled disabled 属性规定应该禁用的 元素。
form form 属性规定 元素所属的一个或多个表单。
formaction 属性规定当表单提交时处理输入控件的文件的 URL。(只针对 type=“submit” 和 type=“image”)
formenctype 性规定当表单数据提交到服务器时如何编码(只适合 type=“submit” 和 type=“image”)。
formmethod 定义发送表单数据到 action URL 的 HTTP 方法。 (只适合 type=“submit” 和 type=“image”)
formnovalidate formnovalidate 属性覆盖 元素的 novalidate 属性。
formtarget 规定表示提交表单后在哪里显示接收到响应的名称或关键词。(只适合 type=“submit” 和 type=“image”)
height 规定 元素的高度。(只针对type=“image”)
list 属性引用 元素,其中包含 元素的预定义选项。
max 属性规定 元素的最大值。
maxlength 属性规定 元素中允许的最大字符数。
min 属性规定 元素的最小值。
multiple 属性规定允许用户输入到 元素的多个值。
name name 属性规定 元素的名称。
pattern pattern 属性规定用于验证 元素的值的正则表达式。
placeholder placeholder 属性规定可描述输入 字段预期值的简短的提示信息 。
readonly readonly 属性规定输入字段是只读的。
required 属性规定必需在提交表单之前填写输入字段。
size size 属性规定以字符数计的 元素的可见宽度。
src src 属性规定显示为提交按钮的图像的 URL。 (只针对 type=“image”)
step step 属性规定 元素的合法数字间隔。
type type 属性规定要显示的 元素的类型。
value 指定 元素 value 的值。
width width 属性规定 元素的宽度。 (只针对type=“image”)
1. accept

accept属性是一个字符串,它定义了文件 input 应该接受的文件类型。这个字符串是一个以逗号为分隔的唯一文件类型说明符列表。由于给定的文件类型可以用多种方式指定,因此当你需要给定格式的文件时,提供一组完整的类型指定符是非常有用的。

  • 简单的来说,这个属性就是用来限制用户选择的文件类型的
  • 来看一下例子吧
<!--
比如我们要选择的是一个`word`文件,就可以这么使用
-->
<input  type='file' accept='.doc, .docx' />


<!--
一个文件选择器需要能被表示成一张图片的内容,包括标准的图片格式和 PDF 文件
-->
<input type="file" accept="image/*,.pdf">

2.file属性

FileList 对象每个已选择的文件。如果 multiple 属性没有指定,则这个列表只有一个成员。

3. multiple

当指定布尔类型属性, 文件 input 允许用户选择多个文件。

<input type="file" multiple name="uploads" id="uploads">
<!-- 表示可以选择多个文件-->
4. name

指定上传的文件名。

1.2 文件的异步上传

借助ajax + formData实现

2. 开始实现文件上传

talk is cheap, show me the code

2.1直接使用form表单同步上传

  • 前端
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Form 文件上传 </title>
</head>
<body>
    <form action='http://127.0.0.1:3000/formData/uploadFile' method='POST' enctype='multipart/form-data' >
        <input type='file' name='file' />
        <br />
        <input type='submit' value='上传文件' />
    </form>
</body>
</html>
  • 后端
'use strict';
const koa = require('koa')
const router = require('koa-router')();
const path = require('path')
const cors = require('koa2-cors')
const multer = require('koa-multer')
const app = new koa()

app.use(cors())
const storage = multer.diskStorage({
    // 存储的位置
    destination: path.join(process.cwd(), "upload"),
    // 文件名
    filename(req, file, cb) {
        const filename = file.originalname.split(".")
        //   利用时间戳来命名接收到的文件
        cb(null, `${Date.now()}.${filename[filename.length - 1]}`)
    }
})
const upload = multer({ storage });

// const upload = multer({ dest: 'uploads/' })
// 使用简版的,只能保存文件,却不能保持文件格式,或者说接收到文件的保存命名自定义

router.post('/formData/uploadFile', upload.single("file"), async ctx => {
    console.log(ctx.req.file)
    // req是node原生的request对象
    ctx.status = 201
    ctx.body = {
        file: ctx.req.file,
        request: ctx.request
    }
})

app.use(router.routes()).use(router.allowedMethods())
app.listen(3000, () => {
    console.log('server is running at:\r\nhttp://localhost:3000')
})

这里使用的是koa, koa-multer实现文件的上传,注意koa-multer其实就是封装了express版本的multer,这也可以看出来koa2的很多中间间都是直接封装express的,在使用的时候,可能要注意ctx.reqctx.request的区别。

此外,该方式仅适用于较小文件的上传,大文件一般使用断点上传,避免传输中断,重新传输,浪费资源。

Multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件。它是写在 busboy 之上非常高效。

注意: Multer 不会处理任何非 multipart/form-data 类型的表单数据。

multer/README-zh-cn.md at master · expressjs/multer (github.com)

  • 比如说,这个时候,我们给后端发一个js创建的FormData数据时,上面写的node服务就会报错

[后端基础] 文件上传的发展史,大后端,okhttp,android

  • 这个时候就要使用到下面的方法了。

2.2 通过FormData ajax方式

  • 前端
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js"></script>
    <title>formdata文件上传</title>
  </head>
  <body>
    <form>
      <input type="file" id="uploadFile" />
      <br />
      <button onclick="upload(event)">upload</button>
    </form>

    <script>
      const uploadFileEle = document.querySelector("#uploadFile");
      const $http = axios.create({
        baseURL: "http://127.0.0.1:3000/ajax/",
        timeout: 60000,
      });

      async function upload(event) {
        event.preventDefault();
        if (!uploadFileEle.files.length) return;
        const file = uploadFileEle.files[0]; // 获取单个文件
        console.log(file);
        let formData = new FormData()
        
        // 注意这里的key要跟后端的一致
        formData.set('file', file)
        console.log(formData.entries())
        $http.post('/uploadFile', formData).then(r=>{
            console.log(r)
        }).catch(e=>{
            console.error(e)
        })

      }

    </script>
  </body>
</html>

上传表单的样子

[后端基础] 文件上传的发展史,大后端,okhttp,android

查看源

[后端基础] 文件上传的发展史,大后端,okhttp,android

  • 后端
'use strict';
const koa       =       require('koa')
const koaBody   =       require('koa-body')
const router    =       require('koa-router')();
const fs        =       require('fs')
const path      =       require('path')
const cors      =       require('koa2-cors')

const app = new koa()

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

app.use(cors())

router.get('/', async(ctx)=>{
    ctx.body = 'hello'
})
// 上传一个文件
router.post('/ajax/uploadFile', async(ctx)=>{
    // 上传单个文件
    // console.log(ctx.request)
    const { files } = ctx.request;
    const { file } = files // 获取上传文件
    // 这里的file是前端formData文件的key

     // 读取文件的二进制数据
    const fileData = fs.readFileSync(file.path);
    const prefix = path.join(__dirname, `/upload/`)
    const filePath = prefix + file.name
    
    // 创建目录,不然会报错呜呜
    !fs.existsSync(prefix) && fs.mkdirSync(prefix)
    // 写文件

    const writer = fs.createWriteStream(filePath, {
        flags:'w'
    })
    
    writer.write(fileData);

    ctx.status = 201
    ctx.body = {
        file: fileData
    }

})

app.use(router.routes()).use(router.allowedMethods())
app.listen(3000,()=>{
    console.log('server is running at:\r\n http://localhost:3000')
})
  • 后端使用的是koa2, koa-body

2.3 大文件的断点上传

  • 再说吧,休息一下

附:

唯一文件类型说明符

唯一文件类型说明符是一个字符串,表示在 file 类型的input元素中用户可以选择的文件类型。每个唯一文件类型说明符可以采用下列形式之一:文章来源地址https://www.toymoban.com/news/detail-788596.html

  • 一个以英文句号(“.”)开头的合法的不区分大小写的文件名扩展名。例如: .jpg.pdf.doc
  • 一个不带扩展名的 MIME 类型字符串。
  • 字符串 audio/*, 表示“任何音频文件”。
  • 字符串 video/*,表示 “任何视频文件”。
  • 字符串 image/*,表示 “任何图片文件”。

. 参考

  1. 漫谈前端进化史之从Form表单到文件上传 | 一个人的孤落时辰 (qinyuanpei.github.io)
  2. HTML 标签 (w3school.com.cn)
  3. - HTML(超文本标记语言) | MDN (mozilla.org)
  4. HTML input 标签 | 菜鸟教程 (runoob.com)

到了这里,关于[后端基础] 文件上传的发展史的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity发展史

    Unity历史 2004年诞生于丹麦阿莫斯特 2005年06月:Unity 1.0发布 2006年06月:Unity 1.5发布 2007年10月:Unity 2.0发布,增加地形引擎、实时动态阴影,支持DirectX 9,并具有内置的网络多人联机功能。 2008年06月:Unity 支持Will 2008年10月:Unity 支持iphone 2009年03月:Unity 2.5发布,增加对w、

    2024年02月16日
    浏览(45)
  • 细说元宇宙发展史

    元宇宙作为时下一个热门的产业,凭借着强大的潜力,吸引了全球范围内大量企业的参与。但事实上,元宇宙这一概念,并非是一个全新的名词,它早在数十年前就已经出现在我们的视野当中,那么,就让我们来探索元宇宙的这一段发展时吧,进一步深度了解什么是元宇宙。

    2023年04月10日
    浏览(42)
  • 大数据技术发展史

    大数据(Big Data)是指在传统数据处理方法难以处理的情况下,需要新的处理模式来具有更强的决策力、洞察发现力和过程优化能力的海量、高增长率和多样化的信息资产。大数据的特征通常被概括为“4V”,即: Volume(容量) :大数据的规模非常庞大,通常以 TB(太字节)

    2024年01月19日
    浏览(48)
  • C++发展史

    目录 什么是C++ C++的发展史 C++的重要性 C++在实际工作中的应用 “21天教你学会C++” 先看看祖师爷,记得多拜拜🤭 C语言是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的 程序,需要高度的抽象和建模时,C语言则不合适。为了解决软件危机,

    2024年01月18日
    浏览(50)
  • Windows系统发展史

    1.Windows1.0是由微软在1983年11月宣布,并在两年后(1985年11月)发行的。严格来说,这并不是微软的首个操作系统,毕竟早在1981年,微软就发布了微软操作系统中的里程碑--MS-DOS(MicroSoft Disk Operating System)。与当时的主流操作系统MS-DOS相比,Windows 1革命性地将GUI(图形操作界面)引入到

    2024年02月07日
    浏览(44)
  • Linux发展史

     1、Linux前身-Unix诞生 1965年,贝尔实验室Bell、麻省理工学院MIT、奇异公司GE,发起了Multics计划,让主机可以达成300个终端。后来因为资金不足、计划进度等问题,退出了研究。贝尔研究室退出了Multics计划。1968年Multics 项目到后期由于开发进度不是很好,MIT 和Bell实验室相继离

    2024年02月05日
    浏览(53)
  • 大语言模型发展史

    2023年可谓是生成式AI元年,大语言模型从崭露头角到锋芒毕露,已然成为人工智能领域的关键推动力。这一创新性的技术不仅在自然语言处理领域崭露头角,更深刻地改变了我们对人机交互、智能助手和信息处理的认知。那么大语言模型的发展历程如何呢?由我来剖析其演进

    2024年02月03日
    浏览(55)
  • YOLO系列发展史

    YOLO(You Only Look Once)是一种目标检测算法,由Joseph Redmon等人在2015年提出。它的主要思想是将目标检测任务看作是一个回归问题,并且可以在一个神经网络中同时预测目标的位置和类别。 自2015年YOLO第一次发布以来,YOLO系列经历了多次更新和改进,以下是YOLO系列的发展史:

    2024年02月12日
    浏览(46)
  • unity简介和发展史

    Unity是一款由Unity Technologies公司研发的跨平台2D/3D游戏引擎。它以交互的图型化开发环境为首要方式,编译器运行在Windows 和Mac OS X下,可发布游戏至Windows、Wii、OSX、iOS或HTML5等众多平台。此外,Unity 还是被广泛用于建筑可视化、实时三维动画等类型互动内容的综合型创作工具

    2023年04月10日
    浏览(34)
  • DevOps的发展史了解

    DevOps的历史发展史可以追溯到2000年代初期,当时软件开发行业开始意识到,软件开发和IT运维之间的问题已经成为阻碍软件开发速度和效率的重要因素。在此之前,软件开发和IT运维是两个相对独立的过程,开发人员开发软件并将其交付给运维团队,运维团队负责安装、配置

    2024年02月04日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包