网络互连模型 (应用层 -- HTTP)

目录

HTTP

报文格式

请求报文

响应报文

ABNF

ABNF - 规则定义

报文格式 ~ HTTP-message

报文格式 ~ request-line

报文格式 ~ status-line

报文格式 ~ header-field

报文格式 ~ message-body

URL编码

Xshell模拟HTTP请求

请求方法

头部字段 

请求头字段

响应头字段

Access-Control-Allow-Origin 分析

Set-Cookie 分析 

Cache-Control 分析

状态码

常见状态码

Form表单


HTTP

HTTP(Hyper Text Transfer Protocol), 译为超文本传输协议, 是互联网中应用最广泛的应用层协议之一
设计HTTP最初的目的是: 提供一种发布和接收HTML页面的方法, 由URI来标识具体的资源, 后面用HTTP来传递的数据格式不仅仅是HTML, 应用非常广泛

  • 1991年, HTTP/0.9: 只支持GET请求方法获取文本数据(比如HTML文档), 且不支持请求头、响应头等, 无法向服务器传递太多信息
  • 1996年, HTTP/1.0: 支持POST、HEAD等请求方法, 支持请求头、响应头等, 支持更多种数据类型(不再局限于文本数据), 浏览器的每次请求都需要与服务器建立一个TCP连接, 请求处理完成后立即断开TCP连接
  • 1997年, HTTP/1.1: 支持PUT、DELETE等请求方法, 采用持久连接(Connection: keep-alive), 多个请求可以共用同一个TCP连接
  • 2015年, HTTP/2.0
  • 2018年, HTTP/3.0

报文格式

请求报文

请求报文实例 - GET请求

请求报文实例 - POST请求


响应报文

响应报文实例


ABNF

ABNF(Augmented BNF): 是BNF(Backus-Naur Form,译为:巴科斯-瑙尔范式)的修改、增强版。在RFC 5234中表明:ABNF用作internet中通信协议的定义语言。ABNF是最严谨的HTTP报文格式描述形式, 脱离ABNF谈论HTTP报文格式, 往往都是片面、不严谨的

ABNF - 规则定义

报文格式 ~ HTTP-message

 

报文格式 ~ request-line

示例: 
     GET /hello/ HTTP/1.1

报文格式 ~ status-line

示例: 
    HTTP/1.1 200
    HTTP/1.1 200 OK 

报文格式 ~ header-field

示例:
    Host: localhost:8080
    Connection: keep-alive 

报文格式 ~ message-body

示例:
    username=123&password=456

URL编码

URL中一旦出现了一些特殊字符(比如中文、空格),  需要进行编码; 在浏览器地址栏输入URL时, 是采用UTF-8进行编码
示例:
    编码前:https://www.baidu.com/s?wd=华为
    编码后:https://www.baidu.com/s?wd=%E5%8D%8E%E4%B8%BA

 

Xshell模拟HTTP请求


请求方法

RFC 7231, section 4: Request methods: 描述了8种请求方法: GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE
RFC 5789, section 2: Patch method: 描述了PATCH方法

  • GET :  常用于读取的操作, 请求参数直接拼接在URL的后面(浏览器对URL是有长度限制的)
  • POST : 常用于添加、修改、删除的操作, 请求参数可以放到请求体中(没有大小限制)
  • HEAD :  请求得到与GET请求相同的响应, 但没有响应体(使用场景举例: 在下载一个大文件前, 先获取其大小, 再决定是否要下载。以此可以节约带宽资源)
  • OPTIONS :  用于获取目的资源所支持的通信选项, 比如服务器支持的请求方法OPTIONS * HTTP/1.1
  • PUT :  用于对已存在的资源进行整体覆盖
  • PATCH :  用于对资源进行部分修改 (资源不存在, 会创建新的资源)
  • DELETE :  用于删除指定的资源
  • TRACE :  请求服务器回显其收到的请求信息, 主要用于HTTP请求的测试或诊断
  • CONNECT :  可以开启一个客户端与所请求资源之间的双向沟通的通道, 它可以用来创建隧道(tunnel), 可以用来访问采用了SSL(HTTPS)协议的站点

头部字段 

头部字段可以分为4种类型:
请求头字段(Request Header Fields):  有关要获取的资源或客户端本身信息的消息头
响应头字段(Response Header Fields):  有关响应的补充信息, 比如服务器本身(名称和版本等)的消息头
实体头字段(Entity Header Fields):  有关实体主体的更多信息, 比如主体长度(Content-Length)或其MIME类型
通用头字段(General Header Fields):  同时适用于请求和响应消息, 但与消息主体无关的消息头                                                            

请求头字段

注: q值越大, 表示优先级越高; 如果不指定q值,默认是1.0 (1.0是最大值)

响应头字段


Access-Control-Allow-Origin 分析

前端项目部署在: http://localhost:63342/,  服务端项目部署在: http://localhost:8080/

情景1: 服务端没有设置Access-Control-Allow-Origin

① 当前端页面中使用ajax发送请求获取服务端数据时, 由于该请求为跨域且服务端没有设置Access-Control-Allow-Origin响应头信息, 那么浏览器将拒绝获取数据

② 通过wireshark抓包可以看到服务端是返回了数据的

 情景2: 服务端设置了Access-Control-Allow-Origin

① 客户端发送跨域请求, 获取服务端数据成功

 ② wireshark抓包分析

 

Set-Cookie 分析 

Cache-Control 分析

缓存 - 响应头: 
Pragma:
作用类似于Cache-Control, HTTP/1.0的产物

Expires: 缓存的过期时间(GMT格式时间), HTTP/1.0的产物

Cache-Control: 设置缓存策略
    no-storage: 不缓存数据到本地
    public: 允许用户、代理服务器缓存数据到本地
    private: 只允许用户缓存数据到本地
    max-age: 缓存的有效时间(多长时间不过期), 单位秒
    no-cache: 每次需要发请求给服务器询问缓存是否有变化, 再来决定如何使用缓存
(优先级: Pragma > Cache-Control > Expires)

Last-Modified: 资源的最后一次修改时间

ETag: 资源的唯一标识(根据文件内容计算出来的摘要值)
(优先级: ETag > Last-Modified)

缓存 - 请求头:
If-None-Match
    如果上一次的响应头中有ETag, 就会将ETag的值作为该请求头的值
    如果服务器发现资源的最新摘要值跟If-Node-Match不匹配, 就会返回新的资源(200 OK); 否则, 就不会返回资源的具体数据(304 Not Modified)

If-Modified-Since
    如果上一次的响应头中没有ETag, 有Last-Modified, 就会将Last-Modified的值作为该请求头的值
    如果服务器发现资源的最后一次修改时间晚于If-Modified-Since, 就会返回新的资源(200 OK); 否则, 就不会返回资源的具体数据(304 Not Modified)

Last-Modified与ETag的对比:
Last-Modified的缺陷:
     ① 只能精确到秒级别, 如果资源在1秒内被修改, 客户端将无法获取最新的资源数据
     ② 如果某些资源被修改了(最后一次修改时间发生了变化), 但是内容并没有任何变化, 将会导致相同数据被重复传输, 没有使用到缓存

ETag:
     ① 只要资源的内容没有变化, 就不会重复传输资源数据
     ② 只要资源的内容发生了变化, 就会返回最新的资源数据给客户端


状态码

状态码指示HTTP请求是否已成功完成, 状态码可以分为5类:
   ① 信息响应: 100~199
   ② 成功响应: 200~299
   ③ 重定向: 300~399
   ④ 客户端错误: 400~499
   ⑤ 服务器错误 : 500~599

常见状态码

100 Continue:
    ① 请求的初始部分已经被服务器收到, 并且没有被服务器拒绝。客户端应该继续发送剩余的请求, 如果请求已经完
成, 就忽略这个响应
    ② 允许客户端发送带请求体的请求前, 判断服务器是否愿意接收请求(服务器通过请求头判断)
    ③ 在某些情况下, 如果服务器在不看请求体就拒绝请求时, 客户端就发送请求体是不恰当的或低效的

200 OK: 请求成功

302 Found: 请求的资源被暂时的移动到了由Location头部指定的URL上

                       

304 Not Modified: 说明无需再次传输请求的内容, 也就是说可以使用缓存的内容

400 Bad Request:由于语法无效, 服务器无法理解该请求

401 Unauthorized:由于缺乏目标资源要求的身份验证凭证

403 Forbidden:服务器端有能力处理该请求, 但是拒绝授权访问

404 Not Found:服务器端无法找到所请求的资源

405 Method Not Allowed:服务器禁止了使用当前HTTP方法的请求

406 Not Acceptable:服务器端无法提供与Accept-Charset以及Accept-Language指定的值相匹配的响应

408 Request Timeout:服务器想要将没有在使用的连接关闭; 一些服务器会在空闲连接上发送此信息, 即便是在客户端没有发送任何请求的情况下

500 Internal Server Error:所请求的服务器遇到意外的情况并阻止其执行请求

501 Not Implemented:请求的方法不被服务器支持, 因此无法被处理; 服务器必须支持的方法(即不会返回这个状态码的方法)只有 GET 和 HEAD

502 Bad Gateway:作为网关或代理角色的服务器, 从上游服务器(如tomcat)中接收到的响应是无效的

503 Service Unavailable:服务器尚未处于可以接受请求的状态; 通常造成这种情况的原因是由于服务器停机维护或者已超载

Form表单

action:请求的URI
method:请求方法(GET、POST)
enctype:POST请求时, 请求体的编码方式
   ① application/x-www-form-urlencoded(默认值): 用&分隔参数, 用=分隔键和值, 字符用URL编码方式进行编码
   ② multipart/form-data: 文件上传时必须使用这种编码方式

multipart/form-data格式标准: 

enctype = application/x-www-form-urlencode 请求分析:

代码:

<form action="/hello/form" method="post" enctype="application/x-www-form-urlencoded">
    <div>
        <span>姓名</span>
        <input type="text" name="name">
    </div>
    <div>
        <span>年龄</span>
        <input type="text" name="age">
    </div>
    <div>
        <span>照片</span>
        <input type="file" name="photo">
    </div>
    <button type="submit">保存</button>
</form>

测试: 

报文分析: 


enctype = multipart/form-data 请求分析:

代码:

<form action="/hello/form" method="post" enctype="multipart/form-data">
    <div>
        <span>姓名</span>
        <input type="text" name="name">
    </div>
    <div>
        <span>年龄</span>
        <input type="text" name="age">
    </div>
    <div>
        <span>照片</span>
        <input type="file" name="photo">
    </div>
    <button type="submit">保存</button>
</form>

测试: 

  

报文分析: 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值