欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

一文搞懂HTTP协议及相关常见面试题

程序员文章站 2022-06-22 12:46:11
HTTP是什么? HTTP协议也叫Hyper Text Transfer Protocol(超文本传输协议),工作在OSI参考模型的应用层,是一个基于请求与响应模式的无状态的协议,同时也是基于TCP/IP协议来传输数据。 HTTP主要特点 1、主要支持B/S模式:平常我们使用的浏览器可根据url向服 ......

http是什么?

 http协议也叫hyper text transfer protocol(超文本传输协议),工作在osi参考模型的应用层,是一个基于请求与响应模式的无状态的协议,同时也是基于tcp/ip协议来传输数据。

http主要特点

  1、主要支持b/s模式:平常我们使用的浏览器可根据url向服务器发送请求,服务器拿到http报文之后解析并作出响应,将数据传输回浏览器,tcp三次握手建立连接之后传输数据就是http报文与其他的服务器资源

  2、简单快速:客户端向服务器请求服务时,只需要传输请求方法(比如:get,post,put等等)和路径(即url资源定位符)服务器收到就会将对应的资源和响应返回给客户端

  3、灵活:http允许传输任意数据对象,正在传输的类型由content-type加以标记。

  4、无连接:每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。但是在http1.1版本之后,在http1.1中已经默认使用connection: keep-alive,避免了连接建立和释放的开销,但服务器必须按照客户端请求的先后顺序依次回送相应的结果,以保证客户端能够区分出每次请求的响应内容。通过content-length字段来判断当前请求的数据是否已经全部接收。不允许同时存在两个并行的响应。但是无连接永远是http的特性,至于下层的tcp连接是否关闭已经不在http管辖范围之内,所以http协议还是无连接的

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

http请求结构

一文搞懂HTTP协议及相关常见面试题

  下面是我访问https://www.baidu.com的http请求报文

get https://www.baidu.com/ http/1.1\r\n
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
accept-encoding: gzip, deflate, br\r\n
accept-language: zh-cn,zh;q=0.9\r\n
connection: keep-alive\r\n
cookie: ***\r\n
host: www.baidu.com\r\n
upgrade-insecure-requests: 1\r\n
user-agent: mozilla/5.0 (windows nt 10.0; wow64) applewebkit/537.36 (khtml, like gecko) chrome/69.0.3497.100 safari/537.36\r\n
\r\n
  下面是响应报文头部字段名的含义
 
  accept:浏览器可接受的文件类型。
 
  accept-charset:浏览器可接受的字符集。
 
  accept-encoding:浏览器能够进行解码的数据编码方式,比如gzip。servlet能够向支持gzip的浏览器返回经gzip编码的html页面。许多情形下这可以减少5到10倍的下载时间。
 
  accept-language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到。
 
  authorization:授权信息,通常出现在对服务器发送的www-authenticate头的应答中。
 
  connection:表示是否需要持久连接。如果servlet看到这里的值为“keep-alive”,或者看到请求使用的是http 1.1(http 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如applet,图片),显著地减少下载所需要的时间。要实现这一点,servlet需要在应答中发送一个content-length头,最简单的实现方法是:先把内容写入bytearrayoutputstream,然后在正式写出内容之前计算它的大小。
 
  content-length:表示请求消息正文的长度。
 
  cookie:这是最重要的请求头信息之一,某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)就是cookie。所以比较重要,不能随意让其他人获取到自己在网页上的cookie
 
  from:请求发送者的email地址,由一些特殊的web客户程序使用,浏览器不会用到它。
 
  host:初始url中的主机和端口。
 
  if-modified-since:只有当所请求的内容在指定的日期之后又经过修改才返回它,否则返回304“not modified”应答。
 
  pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝。
 
  referer:包含一个url,用户从该url代表的页面出发访问当前请求的页面。
 
  user-agent:浏览器类型,如果servlet返回的内容与浏览器类型有关则该值非常有用。
 
  ua-pixels,ua-color,ua-os,ua-cpu:由某些版本的ie浏览器所发送的非标准的请求头,表示屏幕大小、颜色深度、操作系统和cpu类型。
 
  但是浏览器不一定发所有的请求头字段,而是选取需要的发送,每个网页发送的请求头字段都不一样
 

http响应报文结构

一文搞懂HTTP协议及相关常见面试题

  下面是百度传回来的响应报文

http/1.1 200 ok\r\n
bdpagetype: 2\r\n bdqid: 0xd24a0cab000b1e6e\r\n cache-control: private\r\n connection: keep-alive\r\n content-encoding: gzip\r\n content-type: text/html;charset=utf-8\r\n date: wed, 08 may 2019 03:23:24 gmt\r\n expires: wed, 08 may 2019 03:23:24 gmt\r\n server: bws/1.1\r\n set-cookie: ***\r\n set-cookie: ***\r\n set-cookie: ***\r\n
\r\n

  响应正文就是百度的前端界面代码,最终浏览器会将这个前端展示给我们

下面是响应报文头部字段名的含义:

  allow 服务器支持哪些请求方法(如get、post等)。
 
  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-length 表示内容长度。只有当浏览器使用持久http连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入bytearrayoutputstram,完成后查看其大小,然后把该值放入content-length头,最后通过bytearraystream.writeto(response.getoutputstream()发送内容。
 
  content-type 表示后面的文档属于什么mime类型。servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置content-type,因此httpservletresponse提供了一个专用的方法setcontenttype。
 
  date 当前的gmt时间。你可以用setdateheader来设置这个头以避免转换时间格式的麻烦。
 
  expires 应该在什么时候认为文档已经过期,从而不再缓存它
 
  last-modified 文档的最后改动时间。客户可以通过if-modified-since请求头提供一个日期,该请求将被视为一个条件get,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(not modified)状态。last-modified也可用setdateheader方法来设置。
 
  location 表示客户应当到哪里去提取文档。location通常不是直接设置的,而是通过httpservletresponse的sendredirect方法,该方法同时设置状态代码为302。
 
  refresh 表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setheader("refresh", "5; url=http://host/path")让浏览器读取指定的页面。注意这种功能通常是通过设置html页面head区的<meta http-equiv="refresh" content="5;url=http://host/path">实现,这是因为,自动刷新或重定向对于那些不能使用cgi或servlet的html编写者十分重要。但是,对于servlet来说,直接设置refresh头更加方便。注意refresh的意义是“n秒之后刷新本页面或访问指定页面”,而不是“每隔n秒刷新本页面或访问指定页面”。因此,连续刷新要求每次都发送一个refresh头,而发送204状态代码则可以阻止浏览器继续刷新,不管是使用refresh头还是<meta http-equiv="refresh" ...>。注意refresh头不属于http 1.1正式规范的一部分,而是一个扩展,但netscape和ie都支持它。
 
  server 服务器名字。servlet一般不设置这个值,而是由web服务器自己设置。
 
  set-cookie 设置和页面关联的cookie。servlet不应使用response.setheader("set-cookie", ...),而是应使用httpservletresponse提供的专用方法addcookie。参见下文有关cookie设置的讨论。
 
  www-authenticate 客户应该在authorization头中提供什么类型的授权信息?在包含401(unauthorized)状态行的应答中这个头是必需的。例如,response.setheader("www-authenticate", "basic realm=\"executives\"")。注意servlet一般不进行这方面的处理,而是让web服务器的专门机制来控制受密码保护页面的访问(例如.htaccess)。
 
下面是常见状态码的含义:

  1xx:接受的请求正在处理
  2xx:请求正常处理完毕
    200 ok:请求已经正常处理
    204 no content:请求处理成功但没有资源返回
    206 partial content:是对资源的一部分请求,即响应报文中包含content-range指定的范围实体
  3xx:需要进行附加操作以完成请求
    301 moved permanently:也就是uri在服务器端更新,客户端也要进行书签引用的变更
    302 found:只是临时重定向和301状态码有些相似,但是301是永久性的
    303 see other:303和302有着相同的功能,但303状态码表示客户端需要用到get的方式进行请求
    304 not modified:表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但是请求未能满足服务器所设置的条件
    307 temporary redirect:临时重定向。302有相同的含义。307会遵照浏览器的标准。
  4xx:服务器无法处理请求,可以理解为客户端发送的请求信息有误
    400 bad request:表示请求报文中存在语法错误
    401 unauthorized:表示发送的请求需要有通过http的认证信息,若之前有过请求,这表示请求失败
    403 forbidden:表明对请求资源的访问被服务器拒绝了,但如果想做说明的话,需要在实体的主体部分对原因进行描述
    404 not found:服务器中没有找到资源,或者拒绝访问又不想说明理由的时候
  5xx:服务器处理请求出错。错在服务器这边
    500 internal server error:表明服务器端在执行请求的时候出现了错误
    503 service unavailable:表示服务器正处在超负载或正在进行停机维护

http请求响应步骤

  1、客户端(通常是浏览器)连接到web服务器(一般默认端口号是80),这时候会建立一个套接字连接
  2、发送http请求,通过套接字,客户端就可以向web服务器发送一个请求报文
  3、服务器接收请求并返回http响应,也就是web服务器解析请求定位请求资源,而后服务器再将资源副本写到tcp套接字由客户端读取
  4、如果连接模式为close,那么服务器会主动关闭连接,而客户端是被动关闭连接,若连接模式为keep-alive那么连接就会保持一段时间
  5、最后这一步就是浏览器解析html内容,首先会检查状态行看是否成功,然后解析每一个响应头,最后就是解析前端html代码。浏览器会根据状态码来查看是否要接着解析,比如出现404状态码,浏览器就会展示异常给我们,同样这时它是拿不到响应正文的。

三道面试常考题

1、在浏览器键入url,按下回车之后的流程是什么?

  (1)、dns解析:浏览器会根据url逐层查询dns服务器缓存,解析出url中的域名所对应的ip地址。dns缓存分别有浏览器缓存,系统缓存,路由器缓存,ips服务器缓存,根域名服务器缓存,*域名服务器缓存。从上面的哪一级缓存查询到后直接返回ip地址,不再查询。
  (2)、tcp连接:在得到服务器的ip地址之后,就会尝试和服务器建立连接(具体内容可以看之前的博文tcp协议三次握手和四次握手
  (3)、发送http请求:在浏览器和服务器之间建立好连接之后,浏览器就会发送http请求报文
  (4)、服务器处理请求并返回http报文:服务器返回给浏览器带有html的响应报文
  (5)、浏览器解析渲染页面
  (6)、浏览器释放连接,即tcp四次挥手。
 2、get和post区别
  先来看看请求方法有哪些:
  options:返回服务器所支持的请求方法
  get:向服务器获取指定资源
  head:与get一致,但是只返回响应头,不返回响应正文
  post:向服务器提交数据,数据放在请求体里put 与post相似,只是具有幂等特性,一般用于更新delete 删除服务器指定资源
  trace:回显服务器端收到的请求,测试的时候会用到这个
  connect:预留,暂无使用
  而get和post作为最常用的两个请求方法,究竟区别在哪?
  1、最直观的就是get会将请求的参数放在url中,由于url有长度限制,所以参数不能太多,而post的参数是放在请求报文的正文中,长度没有限制。
  2、get方式主要是对数据库进行查询,所以get是符合幂等性(对数据库无论操作多少次返回的结果是一样的)和安全性(不修改数据库),而post主要用于让数据库增加数据或者删除,修改数据,所以会有一定的安全性问题,需要对post提交的参数做一些安全性检验。
  3、get方式还能被缓存被存储,get请求的url会保存在浏览器的历史记录中,而缓存也是get请求被广泛应用的根本,而post方式除非手动设置,不然不会被缓存。
  4、get方式下产生一个tcp数据包,post产生两个数据包。对于get方式,浏览器会把http请求报文发出去,服务器响应200之后返回响应报文,而post则是浏览器先发http请求头,服务器响应100 continue之后浏览器再发从请求正文过去,服务器响应200并返回数据(但是在firefox浏览器post就只发一次数据包)
3、cookie和session的区别
  前面我们说过http是无状态的,也就是没有记忆功能,那我们的自动登录都是怎么样实现的呢?主要是两种
  第一种方法(浏览器):使用cookie。cookie是服务器发给浏览器的特殊信息,并会以文本形式存在浏览器中,所以我们点击浏览器的清除记录,往往会问我们是否清理cookie,当清理之后下次再访问网页就会需要我们重新登录。如果浏览器中存在cookie,那么提交请求就会一起提交过去服务器在接收到后就会解析cookie生成与客户端相对应的内容,实现自动登录,cookie带有我们的比较重要信息,所以一般不要给被人获取
  第二种方法(服务器):使用session。session是在服务器上保存的信息,当服务器需要为客户创建session的时候,就会解析客户端请求查看请求是否包含session id,如果包含那么就表明此前已经为客户端创建过session,不包含则创建一个对应的session id,而后回发给客户端,使得客户端下次能带有session id。然后按需保存状态
  所以最终的区别总结起来就是:cookie数据存放在客户浏览器上,session数据存放在服务器上,session相对应cookie安全,而使用cookie会给服务器减负
彩蛋:
在访问百度首页,使用浏览器的开发者工具查看console的时候会发现
一文搞懂HTTP协议及相关常见面试题

这也算我写这篇博客的一个收获吧