HTML表单(form)相关知识
本文介绍了HTML表单的基本知识,包括表单的定义、元素、提交方法、验证方式及其在组件库中的应用。表单用于收集用户输入,支持多种元素如<input>、<select>和<textarea>,并通过action和method属性定义提交行为。强调了客户端和服务端的验证方式,以及使用JSON格式提交表单数据的优势。最后,讨论了在Ant Design与Vue中的表单使用方法。
本文介绍了前端开发中网络基础的关键概念,包括HTTP状态码与REST API的关系、TCP/IP协议的三次握手与四次挥手、DNS和DHCP协议、用户状态校验、常见网络攻击及其防范、HTTPS协议及其加密算法、HTTP/2.0的特性以及WebSocket协议的应用。重点强调了安全性和性能优化的重要性。
信息响应 (100–199)
100
- Continue:多用于 POST
请求先发送 HEADER 部分,服务器会响应 100 - Continue
让客户端继续发送 BODY 部分成功响应 (200–299)
200
- OK客户端错误响应 (400–499)
400
- Bad Request:由于被认为是客户端错误(例如,错误的请求语法、无效的请求消息帧或欺骗性的请求路由),服务器无法或不会处理请求。403
- Forbidden:客户端没有访问内容的权限;也就是说,它是未经授权的,因此服务器拒绝提供请求的资源。与 401 Unauthorized
不同,服务器知道客户端的身份。404
- Not Found:服务器找不到请求的资源。在浏览器中,这意味着无法识别 URL。在 API 中,这也可能意味着端点有效,但资源本身不存在。服务器也可以发送此响应,而不是 403 Forbidden
,以向未经授权的客户端隐藏资源的存在。这个响应代码可能是最广为人知的,因为它经常出现在网络上。前提条件:TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;
Q:为什么是三次握手?两次不行吗?
两次握手会省略最后一次客户端重复发送的确认请求,表示服务端收到一个报文就建立连接状态,这可能导致一些问题:
Q:为什么握手只需要三次,而挥手需要四次?
因为必须要确定双方都没有报文要发送时才能关闭连接,因此必须要 (FIN+ACK)x2=4 份报文。
Q:为什么客户端发出第四次挥手的确认报文后要等2MSL的时间才能释放TCP连接?
如果第四次挥手的报文丢失,服务端没收到确认ack报文就会重发第三次挥手的报文,这样报文一去一回最长时间就是2MSL,所以需要等这么长时间来确认服务端确实已经收到了。
由于 HTTP 是无状态协议,即不维护连接的历史信息,你就算连续发送两条报文它也不会连着处理,和分开发也没有任何区别,这在处理一般网页请求时自然没有什么问题,但在涉及一些连续操作如账号管理、购物车等场景时就显得有些力不从心。这时,就需要引入 cookie
来记录状态信息。
cookie 是客户端保存用户信息的一种机制,将服务器发送到浏览器的数据保存在本地(放在 document.cookie
中),下次向同一服务器再发起请求时被携带发送(报文首部里的 With-Credential
字段)。主要用于以下场景:
由于 cookie 都是明文存储在 document.cookie
属性中的(如下图所示),就不能避免被篡改带来的安全风险,这时我们就需要引入 Session。
Session 代表服务器和客户端一次会话的过程,是一种持久网络协议,在用户(或用户代理)端和服务器端之间创建关联,从而起到交换数据包的作用机制。对照Cookie,Session是一种在服务器端保存数据的机制,用来跟踪用户状态的数据结构,可以保存在文件、数据库或者集群中。
也就是说,我们不仅要在客户端存储连接信息,在服务端也要存一份(注意这和 HTTP 的无状态并没有什么关系)。
只要是来自同一用户的请求都在同一个 Session 中处理,这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。
当客户端关闭会话,或者 Session 超时失效时会话结束。
除此之外,Session还有更自由的存储结构,不必受 cookie 的格式、大小限制。
目前大多数的应用都是用Cookie结合SessionId实现跟踪的。第一次创建Session时,服务端会通过在HTTP协议中返回给客户端,在Cookie中记录SessionID,后续请求时传递SessionID给服务,以便后续每次请求时都可分辨你是谁。
为了防止sessionId被修改,还需要附上一些额外的加密信息如时间戳加密。
这里对token稍微展开说说:
CORS 问题真的是折磨前后端萌新的法宝,我当年就被这玩意儿折磨的不轻。
所谓的“同源”指的是“三个相同”:协议相同、域名相同、端口相同。只有这三个完全相同,才算是同源。
同源策略的目的:是为了保证用户信息的安全,防止恶意的网站窃取数据。
在传统 HTTP 协议中,所有数据都是明文传输的,包括敏感信息如用户密码等。
有人或许可以说,我可以在前端进行 Hash+Salt 处理不就可以的吗。但是 Hash 算法如 MD5 是取模运算,是不可逆的,因此在服务端如果不能提前知道取模因子就只能直接拿这个加盐后的值作为密码,这就失去了加密的意义(黑客直接拿到这个明文的加密值也可以登录)。
又有人说了,那我提前把这个取模因子当作“密钥”发过去不就好了?但这个密钥也是明文传输的,因此还是逃不开黑客的魔爪。但是,能想到这一层的话,恭喜你已经摸到了 HTTPS 提出者的思路了。
HTTPS 采用了混合加密算法,具体来说就是对称式加密和非对称式加密混合使用。
为什么要这么干呢?一句话来说就是为了兼顾速度和安全性。
对称加密:加密和解密都是使用同一个密钥,常见的对称加密算法有 DES、3DES 和 AES
缺点:
非对称加密:加密和解密需要使用两个不同的密钥——公钥(public key)和私钥(private key)
HTTPS 在 HTTP 的基础上增加了 SSL (安全套接层) /TLS (安全传输层协议),在建立连接前需要额外的握手协议,在握手过程中将确立双方加密传输数据的密码信息。
值得注意的是,之所以是混合加密,是因为 HTTPS 在内容传输的加密上使用的是对称加密,非对称加密只作用在证书验证阶段。
SSL/TLS是一个安全通信框架,上面可以承载HTTP协议或者SMTP/POP3协议等。
SSL(Secure Socket Layer)安全套接层,是1994年由Netscape公司设计的一套协议,并与1995年发布了3.0版本。
TLS(Transport Layer Security)传输层安全是IETF在SSL3.0基础上设计的协议,实际上相当于SSL的后续版本。
TLS主要分为两层:
上层是TLS握手协议,主要分为握手协议,密码规格变更协议和应用数据协议4个部分
这里对 TLS 的详细实现细节不再叙述。
我们把证书原本的内容生成一份“签名”,比对证书内容和签名是否一致就能判别是否被篡改。这就是数字证书的“防伪技术”,这里的“签名”就叫数字签名。
SSL 证书,或者说 SSL/TLS 证书是 HTTPS 握手的关键所在。
客户端检查服务器的数字 CA(Certification Authority)证书
HTTPS 真的绝对安全吗?显然不是的,毕竟天下没有不透风的墙。举一个简单的例子,如果没有公认的证书颁发机构,我们甚至根本无法确认证书是不是来自我们想要访问的网站!
一些常见的 HTTPS 漏洞如下:
http2.0 是一种安全高效的下一代 http 传输协议。安全是因为 http2.0 建立在 https 协议的基础上,高效是因为它是通过二进制分帧来进行数据传输。
HTTP 1.1最大的槽点之一就是使用明文对头部进行编码而非二进制,这造成了空间的浪费,毕竟有些一个标志位就能解决的东西非要用几十个字节的字符串来描述,对于寸土寸金的 TCP 报文实在是有些浪费。
除了二进制外,分帧也是很重要的一个特性 —— HTTP 2.0把所有传输的信息分割为更小的消息(message),并把消息进一步细分为更小的帧(frame),并对它们采用二进制格式的编码。
比如, HTTP1.x 的首部信息会被封装到 HEADER frame,而相应的 Request Body 则封装到 DATA frame 里面,具体如下图所示。
多路复用对于搞信号的同学来说肯定不陌生,我们先来看看原本的 HTTP 1.x 的 TCP 请求风格吧。
HTTP 1.0 中是没有连接持久化这个概念,首先根据浏览器的解析顺序,我们不能一次性得到完整的 HTML 页面,而是会遇到资源后再进行新的请求。而在 HTTP 1.0 中,我们每次请求都需要建立新的 TCP 连接,重复握手和挥手过程!
HTTP 1.1 中引入了持久连接和管道的概念,这样不用每次请求都去重新开启和新建连接,HTTP默认底层的TCP连接是open的,除非手动告诉它要去关闭。在这种情况下,客户端可以使用同一个连接去和server进行交互,从而极大的提升HTTP的效率。
虽然在HTTP1.1中可以使用同一个连接进行数据传输了,但是对于这个连接来说,其中的请求是一一响应的,他们是有顺序的。如果最前面的请求被阻塞了,后面的请求也得不到响应。这种情况被称为 head-of-line (HOL) blocking。
为了解决这个问题,可以在 client 和 server 端建立多个连接,这样就可以利用多个 connection 并行进行数据的传输,从而提升传输效率。
HTTP1.1需要建立多个TCP连接从而解决并行传输的问题,但是在HTTP/2 中只需要建立一个连接就够了。
得益于新的分帧机制,在这个连接中可以传输多个数据流,每个数据流中又包含多个message包,每个message又被切分为多个数据frame,这些数据帧可以乱序发送,并在接收端根据帧首部信息重新组装。
http1.x的头带有大量信息,而且每次都要重复发送。http/2使用本地索引表+映射机制来减少需要传输的header大小,即双方各自缓存一份头部字段表,在报文头部只存储字段表的索引,同时只在头部更新时传输需要更新的字段。这样既避免了重复header的传输,又减小了需要传输的大小。
http/2使用的是专门为首部压缩而设计的HPACK②算法,使用一份索引表来定义常用的http Header,把常用的 http Header 存放在表里,请求的时候便只需要发送在表里的索引位置即可。
把http消息分为很多独立帧之后,就可以通过优化这些帧的交错和传输顺序进一步优化性能。每个流都可以带有一个31比特的优先值:0 表示最高优先级;2的31次方-1 表示最低优先级。
服务器可以根据流的优先级,控制资源分配(CPU、内存、带宽),而在响应数据准备好之后,优先将最高优先级的帧发送给客户端。高优先级的流都应该优先发送,但又不会绝对的。绝对地准守,可能又会引入首队阻塞的问题:高优先级的请求慢导致阻塞其他资源交付。
分配处理资源和客户端与服务器间的带宽,不同优先级的混合也是必须的。客户端会指定哪个流是最重要的,有一些依赖参数,这样一个流可以依赖另外一个流。优先级别可以在运行时动态改变,当用户滚动页面时,可以告诉浏览器哪个图像是最重要的,你也可以在一组流中进行优先筛选,能够突然抓住重点流。
服务器可以对一个客户端请求发送多个响应,服务器向客户端推送资源无需客户端明确地请求。并且,服务端推送能把客户端所需要的资源伴随着index.html一起发送到客户端,省去了客户端重复请求的步骤。
正因为没有发起请求,建立连接等操作,所以静态资源通过服务端推送的方式可以极大地提升速度。Server Push 让 http1.x 时代使用内嵌资源的优化手段变得没有意义;如果一个请求是由你的主页发起的,服务器很可能会响应主页内容、logo 以及样式表,因为它知道客户端会用到这些东西,这相当于在一个 HTML 文档内集合了所有的资源。
不过与之相比,服务器推送还有一个很大的优势:可以缓存!也让在遵循同源的情况下,不同页面之间可以共享缓存资源成为可能。
注意两点:
当服务端需要主动推送某个资源时,便会发送一个 Frame Type 为 PUSH_PROMISE 的 Frame,里面带了 PUSH 需要新建的 Stream ID。意思是告诉客户端:接下来我要用这个 ID 向你发送东西,客户端准备好接着。客户端解析 Frame 时,发现它是一个 PUSH_PROMISE 类型,便会准备接收服务端要推送的流。
WebSocket 是 HTML5 开始提供的一种浏览器与服务器进行全双工通讯的网络技术,属于应用层协议。它基于TCP传输协议,并复用HTTP的握手通道。
对大部分web开发者来说,上面这段描述有点枯燥,其实只要记住几点:
作者: ChlorineC
创建于: 2023-05-18 15:39:00
更新于: 2025-01-11 21:00:00
版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
本文介绍了HTML表单的基本知识,包括表单的定义、元素、提交方法、验证方式及其在组件库中的应用。表单用于收集用户输入,支持多种元素如<input>、<select>和<textarea>,并通过action和method属性定义提交行为。强调了客户端和服务端的验证方式,以及使用JSON格式提交表单数据的优势。最后,讨论了在Ant Design与Vue中的表单使用方法。
EDM(电子直邮营销)是一种通过电子邮件向特定受众发送商业信息的营销方式,具有独特的HTML编写要求,如兼容性问题和使用<table>布局。EDM编写需遵循特定规则,如使用内联样式和独立代码处理移动端与桌面端。文中还探讨了EDM编写过程中的可读性和维护性问题,并提出了建立EDM框架的建议,以提高代码的可维护性和可读性,强调组件复用和样式管理的重要性。
作者分享了个人博客框架迭代历程:从Hexo迁移到Astro的尝试,到发现Elog平台带来的启发,最终思考将Notion作为内容管理系统的新方案。文章重点描述了作者对博客系统的核心需求——解决创作同步问题,以及在探索NotionNext等解决方案过程中遇到的技术限制和思考。
前端模块化的演变包括CJS、AMD、CMD、UMD和ESM,现代浏览器支持ESM,webpack负责模块处理和打包,确保在浏览器中高效运行模块,支持代码拆分和Tree Shaking以优化性能。