网络编程-网络原理HTTP上

文章目录


上节主要是对http协议的一些最基本的概念做出一些说明, 然后简单介绍了一下如何使用fiddler进行对http请求的抓取, 本节我们更加细致的解释一下HTTP的报文格式相关的问题


HTTP请求/响应的基本结构

我们抓一个包来简单查看一下

请求的基本结构如下

我们的HTTP请求分为下面的几个部分

  • 首行: 请求方法 + URL + 协议版本号
  • 请求头(header): 由键值对组成的结构
  • 空行: 作为header的结束标志, 分割请求头和正文
  • 正文(body): 可以携带信息, 可有可无的存在

响应的基本结构如下

和请求类似, 也分为四个部分

  • 首行: 协议版本号 + 状态码 + 状态码解释
  • 响应头(header): 由键值对组成的结构
  • 空行: 作为header的结束标志, 分割响应头和正文
  • 正文: 可以携带信息

认识URL

URL是什么和基本格式

URL的全程是Uniform Resource Locator 统⼀资源定位符, 描述了资源在网上的存在路径, 也就是说, 根据URL就可以找到某一个网络上的资源


URL的基本格式如下

java 复制代码
协议方案名+(登录信息)+服务器地址(ip(域名)+端口号)
+带层次的文件路径+查询字符串(Quary String)+(片段标识符)

登录信息现在基本上不用了, 片段标识符用的也很少(文档类的网站还有)


我们拿访问leetcode平台的URL举例子

java 复制代码
https://leetcode.cn/

我们访问的leetcode官网, 发现只有, 协议方案名+服务器地址(域名)

这说明URL中的好多内容都是可以省略的, 下面是URL中的内容以及是否可以省略

  • 协议方案名: 明确了当前通信使用的协议, 可以省略, 省略后默认是http://
  • ip地址/域名: 描述了请求的服务器的ip地址(域名), 可以省略, 在html中
  • 端口号: 描述了请求的服务器的目的端口, 可以省略, 省略之后相当于添加默认的端口号, http->80, https->443
  • 带层次的文件路径: 描述了请求的资源的更加具体的地址, 可以省略. 省略后相当于 / .
  • 查询字符串(Quary String): 使用键值对的格式进行存储, 详细的描述了请求的信息内容, 也可以传递一定的信息, 必要时使用encoding进行转码, 可以省略
  • 片段标识符: 可以省略

我们在使用leetcode平台抓一个URL看看

java 复制代码
我们搜索了一个 'N皇后'
https://leetcode.cn/search/?q=N%E7%9A%87%E5%90%8E 

上面的URL中, 有 协议名称+域名(ip)+查询字符串(encoding转码了)


关于ip和域名的关系, 其实就是一回事, 因为ip地址不好被人们所记住使用, 所以想出来使用域名来代替ip地址, 二者通过一种叫做DNS应用层协议进行连接, 值得注意的是
DNS既是一种应用层协议, 也是一套服务器系统, 用来IP和域名之间的相互转换

我们想查询域名所对应的IP地址, 可以在cmd命令行中使用ping命令

java 复制代码
ping + 域名

比如我们想查询 leetcode 平台域名对应的 ip 地址


关于encoding机制

因为URL在定义的时候, 有一些特殊的字符, 可能会影响解析的过程

所以一旦涉及到一些特殊的字符, 那可能就需要进行转码encoding操作, 即把转义的字符, 按照每个字节进行十六进制的转码, 然后在每一个字节前面加上%.

发送到服务器之后, 再进行decoding操作, 对转码的内容, 进行解码 从而可以找到对应的资源

但是发送到服务器之后, 进行decoding的操作, 一般都省略了, 因为我们开发中经常使用的spring系列的框架, 对这里的内容进行封装, 封装了解码的过程...


在浏览器上搜索C++

我们拿到上面的URL进行查看...

由于+号是特殊字符, 所以此处进行了URL encoding, 查询字符串中的C++变成了C%2B%2B

因为+对应的十六进制编码就是2B, 除了这种特殊符号, 包括一些非英文的语言(比如中文), 表情包, 也会进行encoding操作 , 比如我们上面查询的N皇后就是使用了转码操作...


我们给一个URL解码的网站

URL解码

我们尝试解码上面的leetcode上的查询内容, 就会发现, 其实就是N皇后...

认识方法(method)

上面我们说到, 在请求的首行里面, 格式是请求方法+URL+协议版本号

方法表示了这个请求的相关作用

不同的方法代表不同的含义, 但是最常见的只有四个GET POST PUT DELETE

最常用的是 GETPOST

GET方法简介

GET方法的含义是, 获取某一种资源, 我们现在抓一个GET的请求看一看

尝试访问一个搜狗的网页

请求

响应

上面是使用GET请求获取到了一个网页的请求和响应


GET方法的特点

  • 首行的第一部分是GET
  • URL的Quary String可以为空, 也可以不为空
  • header部分有若干键值对结构
  • body部分为空(也可以不为空)
  • GET一般是幂等的...(一般情况)
  • body一般是空的, 如果需要给服务器发送一些数据, 可以通过Quary String进行传输

关于URL的长度问题

下面是引用的解释

关于 GET 请求的 URL ⻓度问题

⽹上有些资料上描述: get请求⻓度最多1024kb 这样的说法是错误的.

HTTP 协议由 RFC 2616 标准定义, 标准原⽂中明确说明: "Hypertext Transfer Protocol -- HTTP/1.1,"

does not specify any requirement for URL length.

没有对 URL 的⻓度有任何的限制.

实际 URL 的⻓度取决于浏览器的实现和 HTTP 服务器端的实现. 在浏览器端, 不同的浏览器最⼤⻓度

是不同的, 但是现代浏览器⽀持的⻓度⼀般都很⻓; 在服务器端, ⼀般这个⻓度是可以配置的.

简单点说, 早期的浏览器版本不支持非常长的URL长度, 但是现在的URL以及完全没有长度的限制了...


关于为什么通常情况下GET方法设置为幂等的问题

幂等的含义就是, 同一个请求获取到的数据是相同的, 由于我们从服务器端获取到的数据, 通常情况下是相同的, 所以设置为幂等之后,

我们的本地就会缓存从服务器加载过来的数据, 从而在下次加载相同的内容的时候, 直接加载缓存到本地的资源就可以了, 从而加速了访问的速度, 传输层面的话, 也可以通过访问CDN服务器来加快访问服务器的过程(本质上是一种分布式存储机制)

如果真的想从新获取一遍资源, 就使用 ctrl + F5 强刷一下

但是随着互联网技术的进步, 很多时候, GET请求通常不设置为幂等的, 因为我们通常需要你的个性化推送这就意味着不能设置为幂等的...

POST方法简介

POST的语义是传输某一种数据信息, 通常使用body部分进行数据的传输, 关于POST最常见的场景就是, 登录, 上传

我们尝试抓取一个POST的信息来看一看

请求

响应

POST方法的特点

  • 首行的第一部分是POST
  • URL的Quary String一般为空(也可以不为空)
  • header部分有多个键值对结构
  • body部分一般不为空, 通过body来向服务器端传递信息

GET和POST的区别(经典面试题)

请你说说 GETPOST 的区别是什么

  • 语义不同:
    GET表示从服务器端获取一些资源, POST表示向服务器端提交一些资源
  • bodyQuary String 部分的不同
    GET请求的body部分通常为空(也可以不为空), POST的body部分通常不为空(也可以为空)
    GET请求的Quary String通常不为空(也可以为空), POST的Quary String通常为空(也可以不为空)
  • 传递数据方式的不同
    GET通过Quary String中的内容传递数据信息, POST通过body传递数据信息
  • 是否幂等(上面GET那里有解释)
    GET请求一般是幂等的, POST请求一般是不幂等的
  • 是否可以被缓存(和幂等相关)
    GET请求可以被缓存, POST请求不能被缓存

关于GET和POST的补充说明

  • 关于语义
    GET完全可以上传资源(通过Quary String), POST方法也可以获取资源(通过body), 所以在实际的开发中, 两个方法的使用并没有明确的界限

  • 关于幂等性
    GET的官方文档建议设置为幂等的, 但是我们实际的开发中也可以根据自己的需求进行开发, 比如主流的网站都有猜你喜欢功能...

  • 关于安全性

    有些资料说, GET不如POST安全, 这实际上是不合理的, 比如在登录的场景, 他的意思其实是, 如果使用GET进行传输, 密码信息会直接显示到浏览器的上面的地址栏 , 所以不安全, 这显然是一种掩耳盗铃的说法...即使你通过POST传输, 我抓一个包也就全知道了, 所以POST也不是很安全, 我们正确的加密传输的方案是在业务层直接进行加密(HTTPS只能保证传输过程中是安全的)

  • 关于传输数据量

    有些资料说, GET传输的数据量不如POST多, 这实质上也是不严谨的, 我们现在的官方标准, 并没有规定GETURL的长度, 也没有规定POST中的body长度, 传输的数据量多少, 完全取决于不同浏览器和服务器的实现, 所以不能简单的说谁比谁传输数据少

  • 关于传输资源类型

    有的资料说, GET只能传输文本数据, POST不仅可以传输文本还可以传输二进制数据, 确实, GET中的URL中的Quary String只能是文本数据, 但是我们要想实现传输二进制的效果, 可以对二进制数据进行URL encoding操作转换为文本数据, 然后传输之后再进行decoding操作进行解码即可


Restful风格

尽管我们的方法之间并没有明确的界限, 但是我们还是遵循一套大致的流程, 分别CRUD操作

  • POST: 新增
  • DELETE: 删除
  • GET: 查询
  • PUT: 修改

在实际的开发中, 我们也可以尽量的遵循这种Restful设计风格来实现代码...

相关推荐
xianwu5432 小时前
反向代理模块1
开发语言·网络·数据库·c++·mysql
小徐同学14184 小时前
BGP边界网关协议(Border Gateway Protocol)路由聚合详解
运维·服务器·网络·网络协议·信息与通信·bgp
阿常115 小时前
计算机网络——OSI和TCP/IP模型
网络·tcp/ip·计算机网络
sumatch5 小时前
RPC是什么?和HTTP区别?
网络协议·http·rpc
费6 小时前
1、云计算
网络·云计算
谁在夜里看海.7 小时前
【Linux-网络】初识计算机网络 & Socket套接字 & TCP/UDP协议(包含Socket编程实战)
linux·运维·服务器·网络·计算机网络
马浩同学8 小时前
【ESP32】ESP-IDF开发 | WiFi开发 | TCP传输控制协议 + TCP服务器和客户端例程
c语言·网络·单片机·mcu·tcp/ip
孤寂大仙v8 小时前
【Linux】进程地址空间与虚拟地址空间
linux·运维·服务器·网络·redis
Unique_yt9 小时前
1.25 实现一个终端的功能
c语言·开发语言·网络
Ljw...9 小时前
TCP协议(网络)
网络·网络协议·tcp/ip·tcp·tcp协议