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请求结构
下面是我访问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/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地址,不再查询。
(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的时候会发现
这也算我写这篇博客的一个收获吧