关于面试:Http是什么?

语言: CN / TW / HK

前言:本文主要是详解的写一下Http协议的概念、Http的使用等相关知识。目的呢是为了自己以后复习可以不用到处找资料!因此欢迎走过路过的大佬拍砖(指点),有错误的地方我会马上站好挨打(修改)!

Http概念

Http (HTTP-Hypertext transfer protocol)是超文本传输协议, 是一个简单的请求-响应协议,HTTP基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII码形式给出;而消息内容则具有一个类似MIME的格式。

  • HTTP默认端口号为80,但是你也可以改为8080或者其他端口。
  • HTTP是无连接的:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
  • HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
  • HTTP是无状态的:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

Http工作方式

HTTP是基于客户/服务器模式,且面向连接的。典型的HTTP事务处理有如下的过程:

(1)客户与服务器建立连接;
(2)客户向服务器提出请求;
(3)服务器接受请求,并根据请求返回相应的文件作为应答;
(4)客户与服务器关闭连接。

URL转Http报文

Http消息结构

客户端请求消息

请求格式:请求行、请求头部、空行、请求正文

请求行

包括以下三点:

  • 请求方法(get、post等),有关请求方法详情我会在下一个章节说明
  • 请求对应的URL地址,它和报文头的Host属性组成完整的请求URL
  • 协议名称及版本号。
 GET test HTTP/1.1
复制代码
请求头部

请求头部包含若干个属性,格式为“头部字段名:值”,服务端据此获取客户端的信息。
作用:HTTP消息的元数据(metadata)

Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Host: www.juejin.cn
复制代码
请求正文(请求体)

请求体将一个页面表单中的组件值通过param1=value1&param2=value2的键值对形式编码成一个格式化串,它承载多个请求参数的数据。不但请求体体可以传递请求参数,请求URL也可以通过类似于“test\name=test&owd=123456”的方式传递请求参数

name=test&owd=123456
复制代码

服务端响应消息

响应格式:状态行、响应报头、空行和响应正文。

状态行

状态行包括以下:

  • 协议版本
  • 状态码,表示请求是否成功(一般用200表示成功),有关状态码我会在其它章节说明
  • 状态描述,代表状态码的含义,(比如成功是OK)
HTTP/1.1 200 ok
复制代码
响应报头

响应报头包含若干个属性,格式为“头部字段名:值”,客户端据此获取服务端返回的信息。
作用:HTTP消息的元数据(metadata)

Access-Control-Allow-Origin: *
cache-control: no-cache
Content-Security-Policy: script-src 'self' blob: filesystem:; object-src 'self' blob: filesystem:;
Content-Type: text/css
复制代码
响应正文

返回给客户端的响应数据,可能是字符数据,也可能是字节数据,是可选的,由服务端决定。

<body>
<!-- test 这仅仅只是一个示例-->
</body>
复制代码

Http请求方式

  • HTTP0.9只支持GET请求。
  • HTTP1.0 定义了三种请求方法: GET, POSTHEAD方法
  • HTTP1.1 新增了六种请求方法:OPTIONSPUTPATCHDELETETRACECONNECT 方法。
  • GET、PUT、DELETE、PATCH是幂等的,POST是非幂等的

Http请求头信息

大部分的请求头信息是不需要过多关注的,只需要知道前面几个常用的就可以了,其他的大致看一眼就好了,还有更多的请求头字段以及用法等就不一一例举啦

字段名说明示例
Accept指定客户端能够接收的内容类型Accept: text/plain, text/html
Accept-Charset浏览器可以接受的字符编码集。Accept-Charset: iso-8859-5
Accept-Encoding指定浏览器可以支持的web服务器返回内容压缩编码类型。Accept-Encoding: compress, gzip
Accept-Language浏览器可接受的语言Accept-Language: en,zh
Accept-Ranges可以请求网页实体的一个或者多个子范围字段Accept-Ranges: bytes
AuthorizationHTTP授权的授权证书Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Cache-Control指定请求和响应遵循的缓存机制Cache-Control: no-cache
Connection表示是否需要持久连接。(HTTP 1.1默认进行持久连接)Connection: close
CookieHTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。Cookie: $Version=1; Skin=new;
Content-Length请求的内容长度Content-Length: 348
Content-Type请求的与实体对应的MIME信息Content-Type: application/x-www-form-urlencoded
Date请求发送的日期和时间Date: Tue, 15 Nov 2010 08:12:31 GMT
Expect请求的特定的服务器行为Expect: 100-continue
From发出请求的用户的EmailFrom: [email protected]
Host指定请求的服务器的域名和端口号Host: www.juejin.cn
If-Match只有请求内容与实体相匹配才有效If-Match: "737060cd8c284d8af7ad3082f209582d"
If-Modified-Since如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT
If-None-Match如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变If-None-Match: "737060cd8c284d8af7ad3082f209582d"
If-Range如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为EtagIf-Range: "737060cd8c284d8af7ad3082f209582d"
If-Unmodified-Since只在实体在指定时间之后未被修改才请求成功If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT
Max-Forwards限制信息通过代理和网关传送的时间Max-Forwards: 10
Pragma用来包含实现特定的指令Pragma: no-cache
Proxy-Authorization连接到代理的授权证书Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Range只请求实体的一部分,指定范围Range: bytes=500-999
Referer先前网页的地址,当前请求网页紧随其后,即来路Referer: ....net/test
TE客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息TE: trailers,deflate;q=0.5
Upgrade向服务器指定某种传输协议以便服务器进行转换(如果支持)Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
User-AgentUser-Agent的内容包含发出请求的用户信息User-Agent: Mozilla/5.0 (Linux; X11)
Via通知中间网关或代理服务器地址,通信协议Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Warning关于消息实体的警告信息Warn: 199 Miscellaneous warning

Http响应头信息

大部分的响应头头信息是不需要过多关注的,只需要知道前面几个常用的就可以了,其他的大致看一眼就好了,还有更多的响应头字段以及用法等就不一一例举啦

字段名说明示例
Age从原始服务器到代理缓存形成的估算时间(以秒计,非负)Age: 10
Accept-Ranges表明服务器是否支持指定范围请求及哪种类型的分段请求Accept-Ranges: bytes
Allow服务器支持哪些请求方法(如GET、POST等)。Allow: GET, HEAD
Cache-Control告诉所有的缓存机制是否可以缓存及哪种类型Cache-Control: no-cache
Content-Language响应体的语言Content-Language: en,zh
Content-Location请求资源可替代的备用的另一地址Content-Location: /index.htm
Content-MD5返回资源的MD5校验值Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==
Content-Range在整个返回体中本部分的字节位置Content-Range: bytes 21010-47021/47022
Content-Encoding文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader("Accept-Encoding"))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。Content-Encoding: gzip
Content-Length表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStream,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。Content-Length: 348
** Content-Type**表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。Content-Type: text/html; charset=utf-8
Date当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。Date: Tue, 15 Nov 2010 08:12:31 GMT
Expires应该在什么时候认为文档已经过期,从而不再缓存它?Expires: Thu, 01 Dec 2010 16:00:00 GMT
Last-Modified文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT
Location表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。Location: ....net/test
Pragma包括实现特定的指令,它可应用到响应链上的任何接收方Pragma: no-cache
Server服务器名字。Servlet一般不设置这个值,而是由Web服务器自己设置。
Proxy-Authenticate它指出认证方案和可应用到代理的该URL上的参数Proxy-Authenticate: Basic

Http状态码

状态码描述定义范围
1xx信息,服务器收到请求,需要请求者继续执行操作100-101
2xx成功,操作被成功接收并处理200-206
3xx重定向,需要进一步的操作以完成请求300-307
4xx客户端错误,请求包含语法错误或无法完成请求400-423
5xx服务器错误,服务器在处理请求的过程中发生了错误500-505

这里介绍几个常见的状态码具体的含义:

  • 200 OK 服务器成功处理了请求(这个是我们见到最多的)
  • 301/302 Moved Permanently(重定向)请求的URL已移走。Response中应该包含一个Location URL, 说明资源现在所处的位置
  • 304 Not Modified(未修改)客户的缓存资源是最新的, 要客户端使用缓存
  • 404 Not Found 未找到资源
  • 500 服务器遇到一个错误,使其无法为请求提供服务

Http版本之间的区别

Http 0.9

  • HTTP/0.9是第一个版本的HTTP协议,已过时。它的组成极其简单,只允许客户端发送GET这一种请求,且不支持请求头。由于没有协议头,造成了HTTP/0.9协议只支持一种内容,即纯文本。不过网页仍然支持用HTML语言格式化,同时无法插入图片
  • HTTP/0.9具有典型的无状态性,每个事务独立进行处理,事务结束时就释放这个连接。由此可见,HTTP协议的无状态特点在其第一个版本0.9中已经成型。一次HTTP/0.9的传输首先要建立一个由客户端到web服务器的TCP连接,由客户端发起一个请求,然后由web服务器返回页面内容,然后连接会关闭。如果请求的页面不存在,也不会返回任何状态码。

Http 0.9 VS Http 1.0

Http 1.0 是HTTP协议的第二个版本,开始在客户端与服务端通讯中指定版本号。
比HTTP 0.9 增加了以下特性:

  • 请求与响应支持头部。
  • 响应对象以一个响应状态码开始。
  • 响应对象不只限于超文本。
  • 开始支持客户端通过POST方法向web服务器提交数据,支持GET、HEAD、POST方法。
  • 支持长连接(但默认还是使用短连接)、缓存机制以及身份认证。

Http 1.0 VS HTTP 1.1

HTTP 1.1 是HTTP协议的第三个版本,目前使用最广泛以及主流的的协议版本
比HTTP1.0增加了以下内容:

  • 默认为长连接

    HTTP/1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP/1.1中默认开启Connection:keep-alive,一定程度上弥补了HTTP/1.0每次请求都要创建连接的缺点。

  • 提供了范围请求功能(宽带优化)

    在HTTP/1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP/1.1则在请求头引入了range头域,它允许值请求资源的某个部分,即返回码是2.6(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。这是支持- 文件断点续传的基础。

  • 提供了虚拟主机的功能(HOST域)

    在HTTP/1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,每一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP/1.1请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。

  • 缓存处理字段

    HTTP/1.1在1.0的基础上加入了一些cache的新特性,引入了实体标签,一般被称为e-tags,新增更为强大的Cache-Control头。

  • 错误通知的管理

    在HTTP/1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。

Http 1.1 VS Http 2.0

HTTP 2.0 是HTTP协议的第四个版本,比HTTP1.1增加了以下内容:

  • 二进制分帧,HTTP/2.0的所有帧都采用二进制编码。

    • 帧:客户端与服务器通过交换帧来通信,帧是基于这个新协议通信的最小单位。
    • 消息:指逻辑上的HTTP消息,比如请求、响应等,由一或多个帧组成。
    • 流:流是连接中的一个虚拟信道,可以承载双向的消息;每个流都有一个唯一的整数标识符(1,2…N)。
  • 多路复用

    多路复用允许同时通过单一的HTTP/2.0连接发起多重的请求-响应消息。有了新的分帧机制后,HTTP/2.0不再依赖多个TCP连接去处理更多并发的请求。每个数据流都拆分成很多互不依赖的帧,而这些帧可以交错(乱序发送),还可以分优先级。最后再在另一端根据每个帧首部的流标识符把它们重新组合起来。HTTP/2.0连接都是持久化的,而且客户端与服务器之间也只需要一个连接(每个域名一个连接)即可。

  • 头部压缩

    HTTP/1.1的首部带有大量信息,而且每次都要重复发送。HTTP/2.0要求通讯双方各自缓存一份首部字段表,从而避免了重复传输。

  • 请求优先级

    浏览器可以在发现资源时立即分派请求,指定每个流的优先级,让服务器决定最优的响应次序。这样请求就不必排队了,既节省了时间,也最大限度地利用了每个连接。

  • 服务端推送

    服务端推送能把客户端所需要的资源伴随着index.html一起发送到客户端,省去了客户端重复请求的步骤。正因为没有发起请求,建立连接等操作,所以静态资源通过服务端推送的方式可以极大地提升速度。

Http缓存机制

感觉需要了解的大佬可以去看看这篇文章,写的超好的!! 彻底弄懂HTTP缓存机制及原理

Http VS HTTPS

想了解的大佬可以看看这篇文章:关于面试:什么是Http,什么是Https

结语

文章若有错误之处,欢迎各位大佬指正。才疏学浅,各位的指教将使我越来越棒!

感谢大佬

硬核!30 张图解 HTTP 常见的面试题
菜鸟教程
HTTP之1 HTTP协议(HTTP协议概述、HTTP消息、缓存控制相关头部、Cookie相关头部)
HTTP协议 (六) 状态码详解
『网络』HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP/2.0的区别
彻底弄懂HTTP缓存机制及原理