无状态:每一次HTTP请求都是独立的,服务器不会自动记得上一次请求发生了什么。
也就是说,客户端(比如浏览器)每发一次HTTP请求,服务器就只处理这一次的内容,处理完了就结束了,不会记住“哦,这个人前几分钟也访问过我”这种信息。
要“有状态”,就得靠额外的技术(比如Cookie、Session、Token等)来实现。
客户端发一次请求 → 服务器收到后处理 → 服务器回一次响应 → 结束。
在传统的HTTP协议模型下,服务器是无法主动向客户端发消息的,只能被动响应。(服务器永远是被动的,只能等客户端来敲门。)
WebSocket协议允许服务器和客户端建立持久连接(服务器可以主动推消息给客户端)
可能需要实时聊天等功能的应用需要这个技术
HTTP/1.0里,默认每发一次请求就断开一次TCP连接。(所以每次请求都重新建一个TCP连接,开销比较大)。
HTTP/1.1改进了,默认用长连接(Keep-Alive),可以复用同一个TCP连接发送多个HTTP请求。但请求之间依然是无状态的,服务器不会因为你复用了同一个TCP连接就记住你的登录信息、购物车内容这些。
使用哪个HTTP版本,是客户端和服务器“协商”决定的
客户端发起请求时(比如浏览器),在请求里带上“我支持哪些HTTP版本”
服务器收到请求后,根据自己支持的版本,选择一个合适的版本来通信
HTTP 请求和响应的结构基本上就是由「头部(Headers)」+「内容(Body)」组成,但内容虽然可以是任意文本或二进制数据,它的格式和编码必须由双方协商好并通过头部说明
HTTP 头部(Header) 是每个 HTTP 请求或响应中携带的键值对集合,用于在客户端和服务器之间传递元信息(metadata)。
// 请求头(Request Headers) // 第一行是请求行 有请求方式(GET) url(/page) HTTP协议版本(1.1) GET /page HTTP/1.1 // 后面是Key: Value Host: www.example.com User-Agent: Mozilla/5.0 Accept: text/html // 除了上面的Key之外 还有其他很多的标准的Key 比如Authorization、Cookie等 // 另外 可以自己自定义Key 这样的Key一般会加上"X-"前缀 不加也可以 只要不和标准冲突即可 // 响应头(Response Headers) // 第一行是状态行 HTTP/1.1 200 OK // 后面也是Key: Value的形式 Content-Type: application/json Content-Length: 42
内容部分(Body)理论上可以是:纯文本(直接包含了HTML、Json、XML…)、二进制(比如图片)等。但是需要提前协商好内容的形式。(Content-Type / Content-Encoding / Content-Length等)
协议://主机名:端口/路径?查询参数#锚点 https://www.example.com:443/products?id=123#reviews
以前(比如2000年代初期):
每次发送数据(比如提交表单),网页都会刷新,URL可能变化,因为是标准的HTTP请求
现代:
请求通过 JavaScript(比如AJAX或fetch)完成,不会刷新页面,也不会改变URL
前端拿到返回的数据,直接更新网页上的内容
Vue.js控制路由,是指前端自己管理URL变化
变化都是在浏览器端完成的,不需要每次都去请求服务器刷新页面(实际上,浏览器URL变了,但服务器端并不知道这些前端路由的细节)
Vue的数据用Apache / Nginx / Caddy之类的服务器托管成静态网站
后端的Go程序也可以使用Apache等进行反向代理(前后端都不用单独处理证书的问题了)
Vue前端通过AJAX(比如axios / fetch)调用Go后端接口。Go服务器不用再处理页面跳转了
总结:
前后端分离的网络负载
前后端分离开发基础(清华大学计算机科学与技术系 2024 秋季学期《软件工程》) https://lab.cs.tsinghua.edu.cn/software-engineering/basic/
HTTPS 和 HTTP 的报文的结构是一样的:依然是「请求/响应头 + 内容体」,用法完全相同。区别在于:HTTPS 在传输层增加了加密和认证机制。
信息安全中的HTTPS