【Http】Http 基础知识 & 服务器开发
前言
今天讲讲 Http,以及其服务器的开发。 Http,大家应该并不陌生,URL 中也会出现 http: 或 https: 这样的前缀。 本期就讲讲 Http 的底层工作原理。 注意(非广告):Http 的所有知识均可在菜鸟教程(runoob.com)中找到,包括状态码、请求/响应头部、请求方法等。 基本内容
Http,全称 HyperText Transfer Protocol,超文本传输协议。 其版本号分 1.0 1.1 2 3,HTTP/2 及以前基于 TCP,HTTP/3 及以后基于 QUIC 及 UDP。 将
超文本传输协议
分开解释,
超文本
:人类认知中,数字、字母、汉字、符号均属于文本。“超文本”即为“超越文字”的文本。例如,浏览的网页一般为 text/html 文本,API 一般使用 application/json 文本。
传输
:两点之间数据互相“共享”,或“请求”,这些都属于传输。
协议
:指“有两个或两个以上的参与方”。Http 中的参与方为“两点”以及传输的“中间方”。 整合起来,Http 的含义就是:
计算机中两点之间传输超文本的一个约定和规范
。 请求
请求格式如下([CrLf]代表换行,斜体字代表注释):
Method
URI
Version
[CrLf]
Key1
:
Value1
[CrLf]
Key2
:
Value2
[CrLf] ……[CrLf]
Key
:
Value
[CrLf] [CrLf]
(空行)
Content
[CrLf] 空行前的内容称为 HTTP Header,空行后内容称为 HTTP Body。 举例:
GET
/
HTTP/1.1
[CrLf]
Accept
:
*/*
[CrLf] [CrLf] 其中,请求方法(Method)为
GET
,路径(URI)为
/
(根目录),版本号(Version)为
HTTP/1.1
,会
在下文详细说明。 请求方法
Http 使用的是“请求—响应”方式,客户端如果需要获取服务端的某个资源,必须先进行请求。 请求方法位于请求报文的最前端,通常为全部大写。 常用的请求方法有:GET、POST、PUT。
Get 请求
,用于静态获取服务端的某一个资源。例如,打开任意网页,浏览器便会给服务器发送 Get 请求。其响应仅取决于服务端,客户端在 Content 中不得携带任何内容。
Post 请求
,主要用于 API 或登录账号,也就是客户端需要上传数据时使用。 例如: POST /login.html HTTP/1.1 Accept: */* Content-Type: application/json Content-Length: 35 {"username":"114","password":"514"}
Put 请求
,主要用于上传文件,也可以代替 Post 使用。 其实 Put 本身也并不常用,因为其无法确定数据的完整性、安全性,也无法保证数据由授信任的主机上传,甚至可能导致覆盖原数据。 请求头
Http 常用请求头如下,
Accept
:指定客户端接受的 MIME 类型以及质量因子。例如:text/html, application/json, text/plain, */*; q=0.2, image/*,代表客户端接受所有数据格式,并且对 image/* 进行处理,使其质量达到 0.2(有助于减小图片大小)。
Accept-Encoding
:指定客户端支持的压缩格式。
Authorization
:授权。
Cookie
:用于标识客户端。服务器可以主动为客户端颁发 Cookie,也可以主动吊销。经常在登录账号时使用,所以 Cookie 也可以用于账户验证。
Connection
:指定连接方式。keep-alive 代表不立刻关闭连接,close 代表立刻关闭连接。
Content-Encoding
:指定请求正文的压缩格式。
Content-Length
:指定请求正文的长度。这有助于服务端决定是否接受该请求。
Content-Type
:指定请求正文的 MIME 类型与编码格式。
Host
:指定服务器地址。
Referer
:指定用户从何 URL 出发访问当前页面。
User-Agent
:浏览器内核类型。 响应
响应格式如下: Version Code Status[CrLf] Key: Value[CrLf] ……[CrLf] [CrLf] Content[CrLf] Version 同上,Code 与 Status 的作用相同,不过 Code 是状态码,Status 是状态说明。 状态码
Http 状态码(Status Code),标识在响应报文的第一行。其为十进制正整数,范围在[100,600]。 状态码分五类:
1XX
,属于信息响应,是 Http 的中间状态,平时不常用。
2XX
,属于正常响应,表示 Http 资源被正常接收。
3XX
,属于重定向响应,会将浏览器的 URL 改为其它 URL。
4XX
,属于请求错误。
5XX
,属于服务器错误。
常用
状态码如下: (100) Continue 继续:表示客户端继续其请求。 (101) Switching Protocols 切换协议:切换至
更高版本
的 Http。 (200) OK 正常:表示请求正常。在响应正文中附带全部资源。 (201) Created 已创建:服务端已经根据客户端请求创建了新的文档。 (202) Accepted 已接受:服务端已经验证请求有效,但暂时不会返回数据。常在服务器繁忙时出现。 (203) Non-Authoritative Information 非授权信息:正常返回数据,但文件为副本。 (204) No Content 无内容:客户端请求正常,但资源为空。 (206) Partial Content 部分内容:服务端处理了请求,但是仅返回资源的部分内容。常在使用 Range 请求头指定资源范围时出现。 (301) Moved Permanently 已移动:服务器资源永久移动。客户端之后不会再次发送请求,而是直接自行重定向。 (302) Found 已找到:服务器资源临时移动。与 301 不同,客户端下次仍需发送请求。 (304) Not Modified 未修改:资源在指定时间段内未被修改,或资源符合客户端的摘要。 (305) Use Proxy 使用代理:需要切换至指定代理以继续访问。常在服务器地址更改时使用。 (307) Temporary Redirect 临时重定向:与 302 类似,但是必须使用 Get 请求进行重定向。 (400) Bad Request 错误的请求:请求错误,但是无法详细说明。服务器应该尽量避免该错误,而是提供详细的错误原因。 (401) Unauthorized 未认证:需要客户端进行认证以继续操作。也可以用于有验证头部,但不正确的情况。 (403) Forbidden 已禁止:拒绝处理请求。 (404) Not Found 未找到:无法找到请求的资源。 (410) Gone 不存在:与 404 类似,但是资源曾经存在过。 (411) Length Required 需要长度:客户端请求头中不包含长度,需要标识。对于服务器开发者,可在服务器繁忙时要求提供长度。 (416) Requested range not satisfiable 请求范围无效:请求头 Range 指示的范围溢出或无效。 (500) Internal Server Error 服务器内部错误:笼统的服务器错误,例如过载或 Expection。同样的,应当尽量避免该错误,而是提供详细错误信息;但有一些信息不宜公开,需做好保密。 (502) Bad Gateway 错误的网关:服务器尝试请求其它服务器或网关时失败。 (503) Service Unavailable 服务不可用:服务器过载/维护/服务尚未开放。 响应头
Http 响应也与请求相似,拥有响应头部。以下为常见响应头部:
Allow
:服务端支持的请求方法。
Content-Encoding
:指定响应正文的压缩格式。
Content-Length
:指定响应正文的长度。
Content-Type
:指定响应正文的 MIME 类型。
Date
:当前(返回响应时)的 GMT 时间。
Expires
:指定缓存过期时间。
Location
:在重定向响应时,指定重定向 URL。
Refresh
:指定刷新页面的时间间隔。注意,该字段表示“n 秒后刷新该页面”而不是“每隔 n 秒刷新该页面”。但如果刷新页面后的响应相同,会重置计时器并重新刷新。
Set-Cookie
:为客户端颁发 Cookie。
WWW-Authenticate
:指定客户端应该提供的授权信息。 服务器开发
以下为个人经验。 制作 Http 服务器,必须要做到:速度快,避错误,反馈准。 后台的代码,不能占用大量资源,而且要尽可能让反应时间小到忽略不计,不能丢出任何一个 Exception,吃不准就用 try。 流程如下:收到请求 → 建立处理线程 → 启动计时器 → 解析请求 → 确认请求语法有效性 → 确认缓存数据有效性 → 读取缓存 → (读取数据库) → 生成响应 → 发送响应。 线程处理时间超时,可以先返回 (202) 已接受;系统或数据库繁忙,返回 (503) 服务不可用,并说明原因;处理过程中出现 Exception 或错误,返回 (500) 服务器内部错误。 数据在缓存与数据库中均无法找到,返回 (404) 未找到,曾经存在过的特例,可以考虑 (410) 不存在;URL 更改,返回 (302) 已找到,但不建议使用 (301) 已移动;请求头部带 Range,需判断文件长度是否接受 Range 的范围,支持则返回 (206) 部分内容,不支持则返回 (416) 请求范围无效。 需要验证的操作,如果有验证头部但无效,则返回 (401) 未认证;无验证头部,返回 (403) 已禁止。 缓存需要避免缓存击穿、雪崩,具体可以去某度搜。 总结
本期讲了 Http 基础知识,包括报文格式、请求方法、请求头部、状态码、响应头部,以及服务端的基础开发,下期还要继续讲 Https 与各种杂项知识。 怎样,是不是感觉 Http 比 TCP 还复杂? 好了,我们下期再见。 字数:4296