HTTP个人记录

深深感觉到自己的记忆宛如金鱼,本科学过一遍,考研计算机网络也复习了,但现在嘛也记不住orz,http是一个需要细究的知识点,这里仅是个人的简单记录,文字主要来源于转载,又给互联网增加无用信息了啊

HTTP简介

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。。

HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

曾经认为http是基于tcp的,但是实际上并非如此,在http3.0的时候,甚至是基于udp的。

HTTP默认端口号为80,也可以改为8080或者其他端口。

以上摘抄自菜鸟教程,在其中还有HTTP注意事项如下

HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。

HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

这里让我感觉到疑惑的是,不是说HTTP1.1引入了keep-alive可以保持一定的连接吗?那这个无连接是否是错误的呢?

我个人的想法是,这里的无连接最主要强调的是每次连接只处理一个请求,而非断开TCP连接,后续的http1.1等都对此问题做出了改善。

HTTP的无状态

这里主要涉及cookie和session

当访问网页进行操作的时候,比如电商,输入了密码登录,如果想要下单购买的时候,因为http无状态,是否还需要再输入一次呢?毫无疑问不用,这是因为cookie和session

http虽然无状态,但应用为了有状态,就给HTTP加了cookie和session机制,让使用http的应用也能有状态,但http还是无状态

cookie和session的区别(来源知乎)

  • Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中

  • Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式

如果禁用了cookie是否session就失效了呢?不是。session可以借助cookie实现,但并非必须。

故而,在爬虫的时候,一些网站需要登录状态,这时候就需要将登录后的cookie保存下来,里面包含了浏览器给你的session,然后可以用这个cookie保持登录进行爬虫。

对于http无状态这个问题更详细的分析,可以参考

http协议无状态中的 “状态” 到底指的是什么?!

URL

以下文字主要来源于此处

v2-1462172cd3712d4af4b161cf7c1fb81c_1440w

超文本传输协议(HTTP)的统一资源定位符将从因特网获取信息的五个基本元素包括在一个简单的地址中:

  • 传送协议。
  • 层级URL标记符号(为[//],固定不变)
  • 访问资源需要的凭证信息(可省略)
  • 服务器。(通常为域名,有时为IP地址)
  • 端口号。(以数字方式表示,若为HTTP的默认值“:80”可省略)
  • 路径。(以“/”字符区别路径中的每一个目录名称)
  • 查询。(GET模式的窗体参数,以“?”字符为起点,每个参数以“&”隔开,再以“=”分开参数名称与数据,通常以UTF8的URL编码,避开字符冲突的问题)
  • 片段。以“#”字符为起点

关于URI和URL

  • URI:Uniform Resource Identifier 统一资源标识
  • URL:Uniform Resource Location 统一资源定位

个人理解,URI唯一的标识了这个资源,而URL可以具体找到它,URL是URI的子集。

举个🌰

http://www.luffycity.com:80/news/index.html?id=250&page=1 为例, 其中:

  • http,是协议;
  • www.luffycity.com,是服务器;
  • 80,是服务器上的默认网络端口号,默认不显示;
  • /news/index.html,是路径(URI:直接定位到对应的资源);
  • ?id=250&page=1,是查询。

大多数网页浏览器不要求用户输入网页中“http://”的部分,因为绝大多数网页内容是超文本传输协议文件。同样,“80”是超文本传输协议文件的常用端口号,因此一般也不必写明。一般来说用户只要键入统一资源定位符的一部分(www.luffycity.com:80/news/index.html?id=250&page=1)就可以了。

由于超文本传输协议允许服务器将浏览器重定向到另一个网页地址,因此许多服务器允许用户省略网页地址中的部分,比如 www。从技术上来说这样省略后的网页地址实际上是一个不同的网页地址,浏览器本身无法决定这个新地址是否通,服务器必须完成重定向的任务。

HTTP字段

客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。

其中请求行包含了请求方法,URI,协议/版本

请求

下面是响应报文格式,主要包含状态行,响应头,响应体。

响应

常见的请求方法

序号 方法 描述
1 GET 请求指定的页面信息,并返回实体主体。
2 HEAD 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头。
3 POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
4 PUT 从客户端向服务器传送的数据取代指定的文档的内容。
5 DELETE 请求服务器删除指定的页面。
6 CONNECT HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
7 OPTIONS 允许客户端查看服务器的性能。
8 TRACE 回显服务器收到的请求,主要用于测试或诊断。
9 PATCH 是对 PUT 方法的补充,用来对已知资源进行局部更新

GET和POST的区别

最直观上的区别是GET提交的数据会放在URL之后,也就是请求行里面,以?分割URL和传输数据,参数之间以&相连,如EditBook?name=test1&id=123456.(请求头里面那个content-type做的这种参数形式,后面讲) POST方法是把提交的数据放在HTTP包的请求体中

举个知乎上的例子,在微博这个场景里,GET的语义会被用在「看看我的Timeline上最新的20条微博」这样的场景,而POST的语义会被用在「发微博、评论、点赞」这样的场景中。

是什么可以参考HTTP 方法:GET 对比 POST - W3School

为什么可以参考GET 和 POST 到底有什么区别? - 大宽宽的回答 - 知乎

请求和响应常见通用头

v2-84b43fb3632d75b0dcaafba4adc9a730_r

状态响应码

状态响应码在响应报文的第一行,[菜鸟教程][https://www.runoob.com/http/http-status-codes.html]中有比较详细的记录

HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:

分类 分类描述
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

比较常见的状态响应码:

状态码 状态码英文名称 中文描述
200 OK 请求成功。一般用于GET与POST请求
400 Bad Request 客户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置”您所请求的资源无法找到”的个性页面
500 Internal Server Error 服务器内部错误,无法完成请求
502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
Content-Type

Content-Type(内容类型),一般是指网页中存在的 Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,这就是经常看到一些 PHP 网页点击的结果却是下载一个文件或一张图片的原因。

Content-Type 标头告诉客户端实际返回的内容的内容类型。

抓包瞅瞅

在wireshark中追踪一条GET的http流

截屏2020-04-03下午3.14.35

红色字体表示GET请求,其中第一行GET…表示请求行,后续表示请求头,其中Connection:keep-Alive表示连接不会中断

其中User-agent用于标识请求者的应用类型、操作系统、软件开发商以及版本号,较为常用的格式如下:

1
User-Agent: Mozilla/<version> (<system-information>) <platform> (<platform-details>) <extensions>

一个简单的反爬虫可以检查User-Agent,但是很容易伪造,想要自己查看的话可以“右键chorme-network-headers”看到自己的User-Agent

蓝色字体表示响应,第一行表示状态行,接下来是响应头,最后一行及剩余是请求报文被加密的结果

http各个版本

HTTP/0.9

早已过时的版本,只接受 GET 一种请求方法,没有在通讯中指定版本号,且不支持请求头。由于该版本不支持 POST 方法,所以客户端无法向服务器传递太多信息。

HTTP/1.0

HTTP1.0最主要的两个问题是无法复用连接队头阻塞(head of line blocking),后者是由于HTTP1.0规定下一个请求必须在前一个请求响应到达之前才能发送。假设前一个请求响应一直不到达,那么下一个请求就不发送,同样的后面的请求也给阻塞了。

除此之外,HTTP 1.0不支持Host请求头字段,WEB浏览器无法使用主机头名来明确表示要访问服务器上的哪个WEB站点,这样就无法使用WEB服务器在同一个IP地址和端口号上配置多个虚拟WEB站点。

HTTP/1.1

HTTP/1.1 把 Connection 头写进标准,并且默认开启持久连接。

除非请求中写明 Connection: close,那么浏览器和服务器之间是会维持一段时间的 TCP 连接,不会一个请求结束就断掉,这里的维持也是有时间限制的,一般是几秒。

对于队头阻塞的问题,HTTP1.1引入了Pipelining 技术,但是由于一些代理服务器不能正确的处理 HTTP Pipelining,浏览器默认是关闭的。

为了提高性能,HTTP 1.1还提供了与身份认证、状态管理和Cache缓存等机制相关的请求头和响应头。

Host也是1.1增加的一个请求头,主要用于实现虚拟主机技术(virtual hosting),虚拟主机即共享主机(shared web hosting),可以利用虚拟技术把一台完整的服务器分成若干个主机,因此可以在单一主机上运行多个网站或服务。

举个栗子,有一台 ip 地址为 61.135.169.125 的服务器,在这台服务器上部署着谷歌、百度、淘宝的网站。为什么我们访问 https://www.google.com 时,看到的是 Google 的首页而不是百度或者淘宝的首页?原因就是 Host 请求头决定着访问哪个虚拟主机。
[来自留兰香的csdn][https://blog.csdn.net/codejas/article/details/82844032]

host字段包括host和port,如果没有制定port,则使用默认端口。

HTTP/2.0

待补充

参考

HTTP/3 竟然基于 UDP,HTTP 协议这些年都经历了啥? - Java劝退师的文章 - 知乎

通过多路复用、二进制流与 Header 压缩等技术,极大地提高了性能,但是还是存在一些问题

HTTP/3.0

待补充

HTTP/3 抛弃 TCP 协议,以全新的视角重新设计 HTTP。其底层支撑是 QUIC 协议,该协议基于 UDP,有 UDP 特有的优势,同时它又取了 TCP 中的精华,实现了即快又可靠的协议。

参考:

菜鸟教程http介绍本文主要转载对象

一个HTTP打趴80%面试者 - flyhero的文章 - 知乎非常好的文章,还记录了典型的Content-Type类型

你猜一个 TCP 连接上面能发多少个 HTTP 请求

十分钟搞懂HTTP和HTTPS协议? - 吾非同的文章 - 知乎

HTTP/2 相比 1.0 有哪些重大改进? - Leo Zhang的回答 - 知乎

http协议无状态中的 “状态” 到底指的是什么?!

HTTP协议超级详解图文并茂的博客