前言:前端现在写项目基本用的都是框架,以前学的 HTML 基础,因为长期不用,细节都忘的七七八八了,不知道各位前端小伙伴看到慌不慌。今天要写的 Form 表单,大有文章。
如果你对 Form 已经不太熟悉了,请再去看一篇文档,给你个菜鸟教程的链接:html-forms
开始之前我先把,前后端的代码,给出来:
前端:
NodeJS 后端:
一、Form 表单提交时最重要的三个属性
-
method
表单触发提交按钮时发送 HTTP 的方法。支持 GET 和 POST 两种,method 的值可以为别的,例如 DELETE ,虽然浏览器不会报错,但是也不起作用,发送请求的时候默认 GET。- GET :会把数据放在 URL 里面。
- POST :会把数据放在请求体里面。
-
action
发送 HTTP 请求的 URL。 -
enctype
只在 POST 请求下有效,表示对请求体的编码方式。-
application/x-www-form-urlencoded (default)
- 数据编码成以
&
分割的键值对,同时以=
分割键值对,字符以 URL 的方式进行编码
- 数据编码成以
-
multipart/form-data
- boundary 分隔符开始
- 表单每部分的描述。
- last boundary 结尾
-
text/plain
(不准使用)
-
二、案例讲解
1. GET 方法默认提交
这种最常见了,不用过多解释了。
GET 方法默认提交2. POST 方法默认提交
提交方式由 GET 的 Query String Parameters 变为 FormData,同时 URL 的参数变为请求体里面去了。
当前时间 Friday, January 22, 2021 17:23:553. POST 方法以 application/x-www-form-urlencoded 编码方法提交
POST 方法默认提交的编码方式就是 application/x-www-form-urlencoded
,所以实验结果同上。
4. POST 方法以 multipart/form-data 编码方法提交
先填写好表单:
再点击提交,查看 network 面板:
诶,请求体里面的数据呢,浏览器看不到,这没办法了,要想观察只能通过抓包来看了,打开 Wireshark 。
抓包结果是不是有点看不懂?正常因为你还没学会 RFC1521 和 RFC822 分别对 multipart 的定义和 multipart-body 的定义。
用我们朴素的情感,我们先想一下,这是一个表单提交,如果还是用 &
符号分隔不同输入框的内容,是不是不是合理,你肯定会说肯定不合理。因为现在的表单里面文件,文件经过编译会造成分隔符 &
难以辨认。肯定需要另一种方式,没错,天选单词——boundary 出现了。
简化下,现在这个复杂表单的数据的,分隔其实长下面这样:
boundary=------WebKitFormBoundarybaOZVQaeWiyOkvuw # 注意每个boundary前面都加了两个--
内容1
boundary=------WebKitFormBoundarybaOZVQaeWiyOkvuw # 注意每个boundary前面都加了两个--
内容1
boundary=------WebKitFormBoundarybaOZVQaeWiyOkvuw-- # 注意结尾又加了两个--
看见没,如果你把 boundary=----WebKitFormBoundarybaOZVQaeWiyOkvuw
换成 &
是不是就是 Form 表单提交时,其携带内容的默认分隔方式,不要因为它太复杂,被吓住了。
来看看,Content-Type 中 boundary 的格式,以 form-data
编码方式发送 HTTP 请求的时候,Content-Type 会自动添加 boundary=----WebKitFormBoundarybaOZVQaeWiyOkvuw
,而且 boundary 的长度为 [0-69]
个字符,字符限制为 US-ASCII。
具体到,每个 input 里面编码的内容,可以一个等式来表达:
multipart-body = preamble 1*encapsulation close-delimiter epilogue
preamble 和 epilogue 都会被丢弃,我们在 Wireshark 里面的抓包啥也没看见,所以不讲。1*encapsulation
表示一到多个 input 的内容。这些内容使用 --boundary
进行分隔,最后结束的时候,分隔符 boundary 后面再加两个 --
,即 --boundary--
。
再来看分隔符里面的内容,分两种情况,如果是单纯的 input, 即不上传电脑里面的文件的 input,它的 Encapsulated multipart part 分两部分:
- Content-Disposition 而且里面只有 name
- 第二个就是此 input 表示的数据了。
如果上传本地文件的话,Content-Disposition 里面多个 filename 文件名,同时多个 content-type 表示文件类型。
关于表单的内容讲完了。但是 Content-Disposition 我的补充下一个常用用法,那就是后端给链接直接下载的时候,你会发现那个链接的 HTTP 头里面的内容大概是这样的:
Content-Disposition: attachment; filename="filename.jpg"
浏览器会直接保存一个 filename.jpg 的文件到本地,一个常见的下载就完成了。详情见 Content-Disposition-MDN
三、最后
这周过的很悲催,先是脖子特别的疼,最严重的那天,随便转转都受不了,然后就是有一天眼睛特别的干涩,接着感冒了,平时感冒不可怕,关键是现在疫情时机,还是挺吓人的,不过还好,我几乎不怎么打喷嚏,偶尔才打一次,不过流清水鼻涕挺烦人。
今天,周五,早上刚到公司,买的豆浆都没来的及喝,结果被通知公司全员去雍和宫小学做核酸检测,然后就去了,到地方我都被惊呆了,长这么大就没见过这么长的队。
但是的夸一句,核酸检测速度真快,刷刷的,所以虽然队伍长,但是也没等多长时间,我还打算这次疫情过去我都不用打疫苗和做核酸检测的呢,还是新冠猛。对了,检测的时候,是捅喉咙的方式,同事都被弄的挺难受的,我正好感冒,喉咙有点发炎,本来有点担心,好在运气不错,没有碰我的喉咙,只采集了我上颚的样本。
对了,今天还有件大事,公司的年会暂缓了,上周末还排练小品呢,看来用不到了。
希望过年的时候,疫情被压制住,大家安心回家几天过年,如果今年不回去的话,我想明年可能也不回去了,因为明年北京有冬奥会,这得酌情留下,凑个热闹。
当前时间 Saturday, January 23, 2021 00:35:17
网友评论