这是《大胖小课》栏目的专题一、《说说文件上传那些事儿》的第一节-《文件上传原理概述》
之前发过一篇长文,内容太长,阅读体验太差,很难读完,换作是我也没这个耐心,所以借此专题进行分段介绍,短小精悍,直达主题。
当然从整体上,内容会更详细一些,也会把安全问题考虑进去。
文件上传-原理概述
以大胖的理解,文件上传的原理很简单,就是根据 http
协议的规范和定义,完成请求消息体的封装和消息体的解析,然后将二进制内容保存到文件。
我们都知道如果要上传一个文件,需要把 form 标签的enctype
设置为multipart/form-data
,同时method
必须为post
方法。
那么multipart/form-data
表示什么呢?
multipart 互联网上的混合资源,资源由多种元素组成,form-data 表示可以使用 HTML Forms 和 POST 方法把这些不同的资源提交到 http 服务器。
multipart/form-data
结构
看下 http
请求的消息体
- 请求头:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryDCntfiXcSkPhS4PN
表示本次请求要上传文件,其中 boundary 表示分隔符,如果要上传多个表单项,就要使用 boundary 分割,每个表单项由———XXX 开始,以———XXX 结尾。
- 消息体- Form Data 部分
每一个表单项又由Content-Type
和Content-Disposition
组成。
Content-Disposition: form-data
为固定值,表示一个表单元素,name
表示表单元素的 名称,回车换行后面就是name
的值,如果是上传文件就是文件的二进制内容。
Content-Type
:表示当前的内容的 MIME 类型,是图片还是文本还是二进制数据。
解析
客户端发送请求到服务器后,服务器会收到请求的消息体,然后对消息体进行解析,解析出哪是普通表单哪些是附件。
怎样解析
可能大家马上能想到通过正则或者字符串处理分割出内容,不过这样是行不通的,二进制buffer
转化为string
,对字符串进行截取后,其索引和字符串是不一致的,所以结果就不会正确,文件虽然能生成,但文件是无效的,除非上传的就是字符串,比如base64
。
不过一般情况下不需要自行解析,目前已经有很成熟的三方库可以使用。
至于如何解析,由于这个会占用很大篇幅,咱们先说完实现,后面的文章在详细说解析原理。
下节预告
既然要上传文件,那肯定要先有个服务支持,也就是需要一个文件上传的接口,一般的不需要前端写,都是对接后端 php、java 等,不过现在前后端知识界限没有那么明确了,都是所谓的全栈了,所以下一节我们先用 node
写一个文件上传接口。