HTTP Status Code 状态码 大全
https://blog.youkuaiyun.com/weixin_42915286/article/details/85929979
本文需要结合【Servlet】阅读:
https://blog.youkuaiyun.com/weixin_42915286/article/details/86380935
————————————————————————————————
HTTP
- 提问:什么是HTTP协议?
HyperText Transfer Protocol 超文本传输协议,是互联网上应用最广泛的一种网络协议;
【建立在TCP/IP基础之上】(HTTP底层是TCP/IP协议)(离开了TCP/IP,所有网络协议都跑不起来),所有WWW文件都要遵守HTTP标准;
HTTP设计之初的目的是为了提供一种发布和接受HTML页面的方法;
只要是Web开发,HTTP都是通用的,HTTP是Web开发的基础;
HTTP 1.0 短连接;HTTP 1.1 长连接(市面上目前90%采用1.1);
- 提问:HTTP 1.0和1.1有什么区别?
1.0是短连接,1.1是长连接;
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接;
长和短指的是【时间长短】,跟距离无关;
在HTTP/1.0中默认使用短连接。
也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接(断连接是很费时的!!!);
当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。
而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:
Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭;
客户端再次访问这个服务器时,会继续使用这一条已经建立的连接;
Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间;
实现长连接需要客户端和服务端都支持长连接。
- 面试提问:看到一个test.html页面,问浏览器发出几次HTTP请求?
<h1>abc</h1>
<img src = "Sunset.jpg"/>
<img src = "Winter.jpg"/>
3次;
- 提问:如何理解HTTP协议是无状态的?
HTTP协议是无状态的,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态;
也就是说,打开一个服务器上的网页和上一次打开这个服务器上的网页之间没有任何联系;
HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。
————————————————————————————————
HTTP Request
客户端连上服务器后,向服务器请求某个Web资源,称之为客户端向服务端发送了一个HTTP请求;
一个完整的HTTP请求包括如下内容:
1.一个请求行;
2.若干消息头;
(空行,一定要有)
3.请求体内容;
消息头的内容不是每一次都一样的,GET和POST的内容都会有差异;
————————————————
请求行 Request Line
【请求方式】
有:GET、POST、HEAD、OPTIONS、DELETE、TRACE、PUT
常用的是:GET、POST(知道两种就够了)
- 高频提问:提问:GET和POST的区别?
1.数据:
GET:在URL后附带的参数是有限制的,其数据容量一般不能超过1K;
POST:可以在请求的实体内容中向服务器发送数据,传送的数据量理论上无限制,一般不超过64K;
2.参数:
GET:请求参数放在URL后,以?
的方式来进行拼接;
POST:请求参数放在HTTP请求包中;
3.用途:
GET:一般用来请求/获取数据;因为GET更快,携带数据量小,无法携带大数量;
POST:一般用来提交数据;安全性更高;POST提交的参数后台更容易解析(即使是中文数据也更容易解决)
————————————————
请求头 Header
【HTTP 请求头 Header 是浏览器发送出去的!!!】
下列是个较完整的结构(一个属性都不能忽视)
Accept:text/html,application/xhtml+xml,application/xml...
Accept-Charset: ISO-8859-1
Accept-Encoding: gzip, deflate, br
Accept-Language: en,zh-CN;q=0.9,zh;q=0.8,zh-TW;q=0.7
Host: www.sohu.com:80
If-Modified-Since: Thu, 01 Aug 2019 14:29:15 GMT
Referer: http://www.sohu.com/login.html
User-Agent: Mozilla/5.0 AppleWebKit/537.36 Chrome/75.0.3770.142 Safari/537.36
Cookie: JSESSIONID=0A67AFAE955419559204D4443E18CB5A
Connection: keep-alive
Date: Thu, 01 Aug 2019 14:29:15 GMT
- Accept:
text/html,application/xhtml+xml,application/xml...
浏览器告诉服务器:我可以接收文本(忽略XML头来编码)、XHTML系列文档、文本(根据XML头来编码); - Accept-Charset:
ISO-8859-1
浏览器告诉服务器:我可以接收字符编码【ISO-8859-1】; - Accept-Encoding:
gzip, deflate, br
浏览器告诉服务器:我可以接收GZIP、DEFLATE、BR算法压缩后的数据; - Accept-Language:
en,zh-CN;q=0.9,zh;q=0.8,zh-TW;q=0.7
浏览器告诉服务器:我支持英文、中国中文、台湾中文; - Host:
www.sohu.com:80
浏览器告诉服务器:我要找的主机是xxx - If-Modified-Since:
Mon, 31 Jul 2019 12:00:00 GMT
浏览器告诉服务器(sohu.com):关于请求行里访问的这个页面/资源,我的缓存中已存在了,但该文件的时间是xxx;
服务器会比较此次时间,若此文件当前时间已发生了变化,会传递一份新文件来,否则不管; - Referer:
http://www.sohu.com/login.html
浏览器告诉服务器:我来自哪里;
Referer的正确英语拼法是referrer。由于早期HTTP规范的拼写错误,为了保持向后兼容就将错就错了。其它网络技术的规范企图修正此问题,使用正确拼法,所以拼法不统一。
他的用法是【防外连接】/【盗链】,比如支付宝付款时,支付宝出于担心野鸡浏览器会乱发送消息,部分浏览器会显示不支持本浏览器; - User-Agent:
Mozilla/5.0 AppleWebKit/537.36 Chrome/75.0.3770.142 Safari/537.36
浏览器告诉服务器:本浏览器内核; - Cookie:
JSESSIONID=0A67AFAE955419559204D4443E18CB5A
- Connection:
keep-alive
浏览器告诉服务器:我保持长连接,发完消息后,我不会关闭连接; - Date:
Thu, 01 Aug 2019 14:29:15 GMT
浏览器告诉服务器:我发送该HTTP请求的时间;
那么能不能在Servlet中除去这些单独的属性呢?
去Servlet一文中页面搜索:结合HTTP来讲Servlet
————————————————
请求体 Request Body
————————————————————————————————
HTTP Response
一个HTTP响应表示服务器向客户端回送的数据;
一个【状态行】;
若干【消息头】;(可选)
(空行)
【实体】内容;(可选)
————————————————
状态行 Status Line
格式比如:
HTTP版本 状态码 原因叙述
HTTP/1.1 200 OK
状态码 Status Code
状态码:是一个三位的十进制数字,表示【服务器】对【请求】的【处理结果】;
注意:状态码分成五个等级,比如说500-599其中不是每个数字都有意义,有的还未定义;
- 100-199
表示成功接收请求,要求客户端继续提交下一次请求才能完整整个处理过程; - 200-299
表示成功接收请求,已完成整个处理过程,常用200
; - 300-399
未完成请求,客户端需要进一步细化请求,比如:请求的资源已经移动到了一个新地址,常用302
、307
; - 400-499
客户端的请求有误,常用404
; - 500-599
服务端出现错误,常用500
;
重点状态码单个讲解:
状态码 200
整个Request和Response过程没有发生错误,最常见;
状态码 302
当你请求一个资源时,服务器返回302,表示让浏览器转向到另一个资源,比如repsonse.sendRedirect("/资源名")
我们结合Servlet做一个测试:
让myservlet在doget中执行语句:redirect到myservlet2;
myservlet2在doget里写一句话:“如果你看到这个页面,表示redirect成功。”;
@WebServlet(name="myservlet",urlPatterns = {"/myservlet"})
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
resp.sendRedirect("/myservlet2");
}
@WebServlet(name = "myservlet2",urlPatterns = "/myservlet2")
public class MyServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
String str = "如果你看到这个页面,表示redirect成功。";
out.println(str);
}
}
另外,还有一种方法也有人写!!!!!
不需要让浏览器判断状态码是什么!!
自己主动定义状态码和Header里的Location即可;
@WebServlet(name="myservlet",urlPatterns = {"/myservlet"})
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
resp.setStatus(302);
resp.setHeader("Location","http://localhost:8080/myservlet2");
}
结果和第一种方法是一样的;
总结:
resp.sendRedirect("/myservlet2");
等于…
resp.setStatus(302);
resp.setHeader("Location","http://localhost:8080/myservlet2");
其实查看源码即可得知:
resp.sendRedirect()
调用了resp.setStatus()
和resp.setHeader()
这两个函数;
状态码 404 Not Found
最常见的错误,客户端瞎写一个URL即可得到;
状态码 500
服务器出现了问题;
模拟服务器问题,我们在Servlet类中写一个int i = 100/0
,报一个 ArithmeticException即可;
回顾问题:Servlet是在哪里执行的?
服务器;
@WebServlet(name="myservlet",urlPatterns = {"/myservlet"})
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
int i = 100/0;
}
————————————————
消息头 Header
重点参数:
Location
、Content-Type
、Refresh
、Content-Disposition
、Expires
、Cache-control
、Pragma
;
(较完整版本,并不是每次Response都有这么多项)
Location:https://www.douban.com/
Server: dae
(或者 Apache Tomcat)
Content-Encoding: br
Content-Length:80
Content-Language:zh-cn
Content-Type: text/html; charset=utf-8
Last-Modified:Thu, 01 Aug 2019 10:00:0 GMT
Refresh:1;url=https://www.douban.com/
Content-Disposition:attachment;filename=aaa.zip
Transfer-Encoding:chunked
Set-Cookie:SS==QO=5Lb_nQ;path=/search
Expires:-1
Cache-Control: must-revalidate, no-cache, private
Pragma:no-cache
Connection: keep-alive
Date:Fri, 02 Aug 2019 05:56:35 GMT
- Location:
https://www.douban.com/
服务器告诉浏览器:我要重新定位的URL; - Server:
dae
(或者 Apache Tomcat)
服务器告诉浏览器:我的Web服务器; - Content-Encoding:
br
服务器告诉浏览器:我发送的资源进行了br压缩算法,你需要解压缩再使用;
网络世界的空间是很宝贵的,虽然5G已经来临,但是压缩还是很重要; - Content-Length:
80
服务器告诉浏览器:我返回的数据大小是80B(压缩过的大小); - Content-Language:
zh-cn
服务器告诉浏览器:我支持中文; - Content-Type:
text/html; charset=utf-8
服务器告诉浏览器:返回内容的格式、编码; - Last-Modified:
Thu, 01 Aug 2019 10:00:0 GMT
服务器告诉浏览器:该资源上次的更新时间;(若更新了,本地缓存可以清除并获一份新数据) - Refresh:
1;url=https://www.douban.com/
服务器告诉浏览器:过几秒时间后,就刷新到什么URL去,可以做到【延时跳转页面】;
Servlet中检验下这个方法:5秒后转到douban.com
:
resp.setHeader("Refresh","5;url=http://www.douban.com");
Servlet中还可以试试,转到的URL写自己,就相当于X秒后刷新页面!!!
resp.setHeader("Refresh","5;url=/自己");
- Content-Disposition:
attachment;filename=aaa.zip
服务器告诉浏览器:文件传来了,你要下载; - Transfer-Encoding:
chunked
服务器告诉浏览器:传输编码(知道就可以了) - Set-Cookie:
SS==QO=5Lb_nQ;path=/search
服务器告诉浏览器:(重点)Cookie信息; - 下面的【Expires + Cache-Control + Pragma】都说明了一件事:要不要缓存?
因为不同的浏览器识别的缓存机制是不同的; - Expires:
-1
(有时间限制)
服务器告诉浏览器:(重点)如何缓存;
-1:代表不过期;
具体时间:代表过期日期时间; - Cache-Control:
must-revalidate, no-cache, private
服务器告诉浏览器:(重点)如何缓存;
Firfox; - Pragma:
no-cache
服务器告诉浏览器:(重点)如何缓存; - Connection:
keep-alive
服务器告诉浏览器:我要 - Date:
Fri, 02 Aug 2019 05:56:35 GMT
服务器告诉浏览器:我要
缓存
缓存页面举例说明:
【Expires + Cache-Control + Pragma】
操作环境:Chrome on Mac
—————————————————
首先搞清楚一个问题:
回车(Enter)刷新和Reload(command+R)刷新是有不同的;
回车刷新:分为两种情况;
- (1).请求的URI在浏览器缓存中未过期;
HTTP请求消息头如下:
Host 192.168.3.174:8080
User-Agent Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language zh-cn,zh;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset GB2312,utf-8;q=0.7,*;q=0.7
Connection keep-alive
HTTP返回状态显示200 OK,但是,后台Nginx服务器的access.log并没有找到该请求的记录,说明请求并没有真正提交到HTTP服务器。而是被浏览器发现缓存中还有 未过期的文件,直接把请求拦截了;
浏览器里显示所谓的“请求头消息”、“响应头消息”都是浏览器“伪造”的。
这种刷新,使用的网络流量是最小的,可以说完全没有,时间消耗也是最少的。
- (2).请求的URI在浏览器缓存中已过期;
此时,浏览器的HTTP请求消息头如下:
Host 192.168.3.174:8080
User-Agent Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language zh-cn,zh;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset GB2312,utf-8;q=0.7,*;q=0.7
Connection keep-alive
If-Modified-Since Mon, 04 Jul 2011 10:12:40 GMT
多了一行If-Modified-Since
,后台Nginx服务器的access.log也找到了该请求的记录;
说明浏览器对这种情况的处理方法是:
再问一下服务器,请求的URI在某个时间之后有没有被修改过,而这个时间是由上次HTTP响应的Last-Modified决定的。
服务器鉴定之后,没有修改的话,返回304 Not Modified,浏览器收到后,从缓存里读出内容;有修改的话,返回200 OK,并返回新的内容。
这种情况,就像你找到一盒已经过期的牛奶,于是问别人,还能不能喝,如果别人说可以,你就把它喝了,如果别人说不行,那你得就另外找一盒新鲜的牛奶。
Reload刷新
其HTTP请求消息头如下:
Host 192.168.3.174:8080
User-Agent Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language zh-cn,zh;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset GB2312,utf-8;q=0.7,*;q=0.7
Connection keep-alive
Pragma no-cache
Cache-Control no-cache
If-Modified-Since
没有了,Cache-Control换成了no-cache
,此外Pragma
行是为了兼容HTTP1.0,作用与 Cache-Control: no-cache是一样的。
意思是,我不要缓存中的文件了,强制刷新,直接到服务器上重新下载;
于是服务器的响应处理与首次请求这个URI一样,返回 200 OK和新的内容。
这种刷新,使用的网络流量是最大的,也是最耗时的。这就像你虽然发现了一盒牛奶,但是把它扔掉了,直接去买一盒新的。
总结:
1.回车在Expires
有效的时候,是不会去请求服务器的,打开调试看到的请求也只是伪造的,比如Chrome可能显示200(cached)(
比正常的200多了) 其实是没有发起实际的缓存,直接读取本地硬盘缓存。
2.command+R
则会发送 Cache-Control: no-cache
,真正的从服务器重新获取文件,此时缓存完全失效。
—————————————————
有个问题:
浏览器在默认情况下会缓存网页页面(缓存是好事,不缓存的话流量过大),这样会出现一个问题;
如果用户习惯通过回车来刷新,就会默认从Cache中取数据(这很可怕,如果网站是个股票网站,代表无法反应实时信息);
(1).有些网站即时性要求很高,因此要求禁止缓存页面,如何处理?
这个要求应该在HTTP响应头里指定好;
禁止缓存:
(配置三个属性是因为各自支持的浏览器不同)
Expires
:-1
Cache-Control
:no-cache
Pragma
:no-cache
因为Expires涉及时间,所以要用setDateExpires!!!
resp.setDateHeader("Expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
因为有些金融网站必须保证随时刷新都能获得最新数据,而有些用户习惯回车刷新,所以为了避免这方面的缺陷,需要设计禁止缓存;
(2).有些网站要求页面缓存一定时间即可,比如缓存一个小时后失效,如何处理?
resp.setDateHeader("Expires",System.currentTimeMillis()+3600*1000);
Chrome on Mac 缓存文件保存在:
/Users/xxxx/Library/Caches/Google/Chrome/Default/Cache
————————————————
实体内容 Response Body
————————————————————————————————
——————————————————
之前写的
面试(包括HTTP和CTP)
会问:如何发送http请求?
防盗链怎么做?
——————————————————————
——————————————————————
- 提问:HTTP常用的状态码有哪些?
大部分同学都知道200、404、500、302错误。
如果连404都不知道,就别做程序员了。
500错误为什么这么常见呢,因为在开发的时候老是出bug,一个大异常抛出来,浏览器就500了。500表示InternalServerError,也就是内部服务器错误,如果不是bug,一般就是数据库挂了。
再多问几个状态码很多人就不知道了,因为大多数公司的软件服务没有走标准的HTTP状态码,很多状态码从来就不会出现。
400 Bad Request
用于参数验证,少了一个参数或者参数类型错误之类的。
502 Bad Gateway
后端服务挂掉或者压力过大的时候, Nginx接到的请求无法及时传递给后端的服务进行处理,这个时候就会出现502错误。这个也非常常见,知乎豆瓣网站经常开小差的时候发生的错误就是这个。
304 Not Modified
极少人知道这个错误,因为大部分后端开发者的前端Javascript开发经验都严重不足。当你用Chrome打开一个经常访问的网站,看看Network传输的静态资源就可以看到很多304状态码。它表示该资源被浏览器缓存了不需要重新请求服务器。
401 Unauthorized
权限不足,这个很好理解,就是资源存在但是不让你访问。
403 Forbidden
资源禁止访问,如果你的IP列为黑名单了,就会发生这种错误。
其实还有很多状态码,但不会在工作中用到,所以就没列举了。
——————————————————————
- 提问:HTTP响应码301和302代表什么?区别是?
301:永久转移;
302:暂时转移;
——————————————————————
- 提问:HTTP有哪些Method?
GET
不解释,如果读者不知道,建议别在IT圈混了。
POST
一般用于创建或者修改资源,在RESTFUL规范里面POST只用来创建资源,并返回201 Created状态码表示创建成功。不过大多数网站都不遵循严格的RESTFUL规范,POST拿来做修改资源的事也是非常常见的。
PUT
用于修改资源,比如修改资源的某个具体属性。
DELETE
用于删除资源。
HEAD
不常用,跟GET差不多,区别就是不返回Body内容,只返回HTTP头信息。一般用于获取资源的元信息,比如长度,修改时间等
OPTIONS
没用过。
TRACE
没用过。
CONNECT
没用过。
后面三个感兴趣的去阅读一下RPC规范。
——————————————————————
- 提问:HTTP协议格式是怎样的?
HTTP的请求和响应的消息协议是一样的,分为三个部分,起始行、消息头和消息体。这三个部分以CRLF作为分隔符。最后一个消息头有两个CRLF,用来表示消息头部的结束。
HTTP请求的起始行称为请求行,形如GET /index.html HTTP/1.1
HTTP响应的起始行称为状态行,形如200 ok
消息头部有很多键值对组成,多个键值对之间使用CRLF作为分隔符,也可以完全没有键值对。形如Content-Encoding: gzip
消息体是一个字符串,字符串的长度是由消息头部的Content-Length键指定的。如果没有Content-Length字段说明没有消息体,譬如GET请求就是没有消息体的,POST请求的消息体一般用来放置表单数据。GET请求的响应返回的页面内容也是放在消息体里面的。我们平时调用API返回的JSON内容都是放在消息体里面的。
——————————————————————
- 提问:什么是分块传送?
当浏览器向服务器请求一个资源时,这个资源是一个动态资源,服务器无法提前预知资源的大小,这个时候就可以使用分块传输。
服务器先生成一个chunk,发送这个chunk,再生成一个chunk,再发送一个chunk,直到全部资源传送完成。
分块传送需要在请求头增加一个特殊的键值对transfer-encoding: chunked,那么消息体的内容便是分块传送的。
——————————————————————
- 提问:持久连接的机制是怎样的?
HTTP早期版本中每个请求都会发起一个连接,一个网页除了页面的HTML之外还会有很多静态资源以及诸多的API调用,如果每个请求都一个连接,势必网页的一次加载就会和服务器创建多次连接,这是非常浪费服务器资源的,同时也让客户端的访问速度慢了不少。HTTP1.0之后引入了Keep-Alive持久连接,在HTTP1.1版本中成为默认选项。它使得HTTP的一个连接可以连续服务多个请求,有效节省了资源,增加了客户端页面的加载速度。
持久连接也不宜一直保持,毕竟每个连接都会占用服务器资源,如果打开网页的人太多,那服务器资源也会紧张,所以一般服务器都会配置一个KeepAlive Timeout参数和KeepAlive Requests参数限制单个连接持续时长和最多服务的请求次数。
如果服务器设置的timeout时长为0,就退化到非持久连接。非持久连接会在响应头部增加一个头信息Connection: Close通知客户端在接受完当前响应后连接需要立即关闭。
同样浏览器也不会因为服务器将KeepAlive Timeout配置了无限长就不管不问一直持续保持连接。每个浏览器都有它自己的内置限制,具体限制浏览器厂商各有不同。
——————————————————————
- 提问:什么叫Pipeline管线化?
HTTP1.0不支持管线化,同一个连接处理请求的顺序是逐个应答模式,处理一个请求就需要耗费一个TTL,也就是客户端到服务器的往返时间,处理N个请求就是N个TTL时长。当页面的请求非常多时,页面加载速度就会非常缓慢。
从HTTP1.1开始要求服务器支持管线化,可以同时将多个请求发送到服务器,然后逐个读取响应。这个管线化和Redis的管线化原理是一样的,响应的顺序必须和请求的顺序保持一致。
——————————————————————
- 提问:如何理解HTTP协议的无状态性?
所谓HTTP协议的无状态性是指服务器的协议层无需为不同的请求之间建立任何相关关系,它特指的是协议层的无状态性。
但是这并不代表建立在HTTP协议之上的应用程序就无法维持状态。应用层可以通过会话Session来跟踪用户请求之间的相关性,服务器会为每个会话对象绑定一个唯一的会话ID,浏览器可以将会话ID记录在本地缓存LocalStorage或者Cookie,在后续的请求都带上这个会话ID,服务器就可以为每个请求找到相应的会话状态。
——————————————————————
- 提问:forward和redirect的区别?
发生位置、URL不同:
Forward:在【服务器】跳转,URL不会变化(因为浏览器不知道该跳转的动作,forward对浏览器来说是透明的)forward只实现了一次HTTP请求,一次请求中的request和response是同一个;这也解释了为什么可以使用request作为域对象进行Servlet之间的通讯;
Redirect:在【浏览器】跳转,URL会发生变化,发出两个HTTP请求,request域是无效的,因为他不是同一个Request对象;
用法不同:
https://segmentfault.com/a/1190000013119518
去往的URL范围不一样:
Forward:服务器跳转到当前Web应用的资源;
Redirect:服务器跳转可以去任何资源;
传递数据类型不同:
Forward:各种数据,包括对象;
Redirect:只能传递字符串;
跳转时间不同:
Forward:执行到跳转语句后就会立刻跳转;
Redirect:整个页面执行完后才会执行跳转;
那么该怎么用?
Forward带着Forward之前的请求参数;Redirect是新的请求;
另外,大多数网站完成登录使用的不会是提交表单的操作,一般使用的都会是AJAX异步提交。要学习JQuery,JS;
——————————————————————
- 提问:TCP和UDP区别?
给予连接和无连接;
系统资源要求:TCP多,UDP少;
流模式和数据报模式;
TCP保证数据正确性,数据顺序;UDP可能丢包,结构更简单,不保证数据顺序;
——————————————————————
- 提问:TCP为什么要三次握手?两次不行吗
因为为了防止已失效的连接请求又传送到服务端,而产生错误;不能;
——————————————————————
- 提问:TCP粘包怎么产生的?
要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,会产生粘包;
接收数据端的应用层没有及时读取接收缓冲区中的数据,会产生粘包;
——————————————————————
- 提问:OSI七层模型?
APSTNDP
——————————————————————
- 提问:cookie和session原理及区别
cookie采用的是客户端的会话状态的一种储存机制。它是服务器在本地机器上存储的小段文本或者是内存中的一段数据,并随每一个请求发送至同一个服务器。
session是一种服务器端的信息管理机制,它把这些文件信息以文件的形式存放在服务器的硬盘空间上(这是默认情况,可以用memcache把这种数据放到内存里面)当客户端向服务器发出请求时,要求服务器端产生一个session时,服务器端会先检查一下,客户端的cookie里面有没有session_id,是否过期。如果有这样的session_id的话,服务器端会根据cookie里的session_id把服务器的session检索出来。如果没有这样的session_id的话,服务器端会重新建立一个。PHPSESSID是一串加了密的字符串,它的生成按照一定的规则来执行。同一客户端启动二次session_start的话,session_id是不一样的。
区别:Cookie保存在客户端浏览器中,而Session保存在服务器上。Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
——————————————————————
- 提问:session产生的session_id放在cookie里面,如果用户把cookie禁止掉,是不是session也不能用了呢?
禁止掉cookie后,session当然可以用,不过通过其他的方式来获得这个sessionid,比如,可以跟在url的后面,或者以表单的形势提交到服务器端。从而使服务器端了解客户端的状态。
——————————————————————
- 提问:为什么说session 比cookie更安全?
真正的cookie存在于客户端硬盘上的一个文本文件,如果两者一样的话,只要cookie就好了,让客户端来分提服务器的负担,并且对于用户来说又是透明的。但实际上不是。
session的sessionID是放在cookie里,要想功破session的话,得分两步:
第一要得到sessionID。攻破cookie后,你要得到sessionID,sessionID是要有人登录,或者启动session_start才会有,你不知道什么时候会有人登录。
第二取有效sessionID。sessionID是加密的,第二次session_start的时候,前一次的sessionID就没有用了,session过期时sessionid也会失效,想在短时间内功破加了密的 sessionID很难。session是针对某一次通信而言,会话结束session也就随着消失了。
使session失效的方法:
1.关闭tomcat 2.重启web应用 3.session时间到 4.无效的session
——————————————————————
- 提问:cookie和session的区别?
Cookie技术是将用户的数据存储到客户端的技术;
Session技术是将数据存储在服务器端的技术,会为每个客户端都创建一块内存空间 存储客户的数据,但客户端需要每次都携带一个标识ID去服务器中寻找属于自己的内 存空间。所以说Session的实现是基于Cookie,Session需要借助于Cookie存储客 户的唯一性标识JSESSIONID;
–①存在的位置:
cookie 存在于客户端,临时文件夹中; session存在于服务器的内存中,一个session域对象为一个用户浏览器服务
②安全性
cookie是以明文的方式存放在客户端的,安全性低,可以通过一个加密算法进行加密后存放; session存放于服务器的内存中,所以安全性好
③网络传输量
cookie会传递消息给服务器; session本身存放于服务器,不会有传送流量
④生命周期(以20分钟为例)
cookie的生命周期是累计的,从创建时,就开始计时,20分钟后,cookie生命周期结束;
session的生命周期是间隔的,从创建时,开始计时如在20分钟,没有访问session,那么session生命周期被销毁。但是,如果在20分钟内(如在第19分钟时)访问过session,那么,将重新计算session的生命周期。关机会造成session生命周期的结束,但是对cookie没有影响
⑤访问范围
cookie为多个用户浏览器共享; session为一个用户浏览器独享
——————————————————————
- 提问:服务器端怎么向客户端发送一个Cookie?
1.创建Cookie:
Cookie cookie = new Cookie(String cookieName,String cookieValue);
示例:Cookie cookie = new Cookie("username","zhangsan");
那么该cookie会以响应头的形式发送给客户端:
注意:Cookie中不能存储中文
2.设置Cookie在客户端的持久化时间:
cookie.setMaxAge(int seconds); ---时间秒
注意:如果不设置持久化时间,cookie会存储在浏览器的内存中,浏览器关闭cookie信息销毁(会话级别的cookie),如果设置持久化时间,cookie信息会被持久化到浏览器的磁盘文件里
示例:cookie.setMaxAge(10*60);
设置cookie信息在浏览器的磁盘文件中存储的时间是10分钟,过期浏览器 自动删除该cookie信息
3.设置Cookie的携带路径:
cookie.setPath(String path);
注意:如果不设置携带路径,那么该cookie信息会在访问产生该cookie的web资源所在的路径都携带cookie信息
示例:
cookie.setPath("/WEB16");
代表访问WEB16应用中的任何资源都携带cookie
cookie.setPath("/WEB16/cookieServlet");
代表访问WEB16中的cookieServlet时才携带cookie信息
4.向客户端发送cookie:
response.addCookie(Cookie cookie);
5.删除客户端的cookie:
如果想删除客户端的已经存储的cookie信息,那么就使用同名同路径的持久化时间为0的cookie进行覆盖即可
——————————————————————
- 提问:服务器端怎么接受客户端携带的Cookie?
Cookie信息是以请求头的方式发送到服务器端的:
1.通过request获得所有的Cookie:
Cookie[] cookies = request.getCookies();
2.遍历Cookie数组,通过Cookie的名称获得我们想要的Cookie
for(Cookie cookie : cookies){
if(cookie.getName().equal(cookieName)){
String cookieValue = cookie.getValue();
}
}
——————————————————————
- 提问:怎样获得属于本客户端的session对象(内存区域)?
HttpSession session = request.getSession();
此方法会获得专属于当前会话的Session对象,如果服务器端没有该会话的Session 对象会创建一个新的Session返回,如果已经有了属于该会话的Session直接将已有 的Session返回(实质就是根据JSESSIONID判断该客户端是否在服务器上已经存在 session了);
2.怎样向session中存取数据(session也是一个域对象)
3.Session对象的生命周期(面试题/笔试题)
——————————————————————
- 提问:怎样向session中存取数据(session也是一个域对象)?
Session也是存储数据的区域对象,所以session对象也具有如下三个方法:
session.setAttribute(String name,Object obj);
session.getAttribute(String name);
session.removeAttribute(String name);
——————————————————————
- 提问:session对象的生命周期?
创建:第一次执行request.getSession()时创建
销毁:
1.服务器(非正常)关闭时
2.session过期/失效(默认30分钟)
问题:时间的起算点 从何时开始计算30分钟?
从不操作服务器端的资源开始计时(例如:当你访问淘宝页面时,点开页面不动,
第29分钟再动一下页面,就得重新计时30分钟;当过了30分钟,就失效了。)
可以在工程的web.xml中进行配置
<session-config>
<session-timeout>30</session-timeout>
</session-config>
3.手动销毁session
session.invalidate();
作用范围:
默认在一次会话中,也就是说在,一次会话中任何资源公用一个session对象;
——————————————————————
- 提问:浏览器关闭,session就销毁了?
不对,浏览器关闭和服务器session销毁没有任何关系!
——————————————————————
总结:购物过程中,cookie与session技术相结合图:
会话技术:
Cookie技术:存到客户端
发送cookie
Cookie cookie = new Cookie(name,value)
cookie.setMaxAge(秒)
cookie.setPath()
response.addCookie(cookie)
获得cookie
Cookie[] cookies = request.getCookies();
cookie.getName();
cookie.getValue();
Session技术:存到服务器端 借助cookie存储JSESSIONID
HttpSession session = request.getSession();
setAttribute(name,value);
getAttribute(name);
session生命周期:
创建:第一次指定request.getSession()
;
销毁:服务器关闭、session失效/过期、手动session.invalidate();
session作用范围:默认一会话中;
——————————————————————
- 提问:?
—————————————————————— - 提问:?
—————————————————————— - 提问:?
—————————————————————— - 提问:?
—————————————————————— - 提问:?
——————————————————————
HTTP简介
https://www.bilibili.com/video/av42873169?from=search&seid=642547716829518288
搞懂了请求和响应,可以说精通了HTTP协议。
也许初级程序员了解了概念就够了,但后期接触到自动化接口设置,必须精通HTTP协议!!
-
提问:什么是协议?Protocol
计算机中的协议和生活中的协议一样,双方或多方遵从共同的规范。
世界计算机的沟通离不开协议的存在。
有HTTP STMP POP TCP/IP等协议;
———————————————————— -
提问:什么是HTTP协议?
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
他是应用层协议,最终需要通过TCP/IP进行传输;
HTTP协议只关注内容本身,传输方面的内容就交给TCP/IP执行;
————————————————————
- 提问:HTTP协议的特点?
(1).(重点)【明文传输,所以安全性较差】;(HTTP无法保障安全,所以很多电商网站登录处会要求下载插件,插件来保障安全,加密过后的文本用HTTP进行传输)
(2).(重点)【无状态协议】;比如网站登录用户名后,一定时间内无需再登录,这是一种保存了客户端状态的场景;单纯的HTTP无法保存状态!!!而现日常生活中能保存是因为用到了Session和Cookie;
(3).【应用层协议,标准化1.1版本】1998年开始到现在;
————————————————————
HTTP是一个基于**TCP/IP(传输控制)**通信协议来传递数据(HTML 文件, 图片文件, 查询结果等),他不关心数据传输的细节,他只用来规定客户端和服务端的数据传输格式;最初是用来向客户传输HTML页面的内容,默认端口是80。
不管你是测试、开发工程师、架构师,HTTP的细节和规则都非常重要!!!
HTTP是基于请求与响应模式的、无状态的、应用层的协议。
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。
HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。
说人话:HTTP协议是客户端和WEB服务器(如Apache/Nginx)间的关系;
原始状态时,两者间没有关系;
当通过客户端打开一个页面时,请求服务器,此时就建立了一个连接(连接是网络上的虚拟电路:比如客户端经过5台路由器+8服务器+3台代理服务器 建立了连接请求);
服务器返回响应信息;
服务器收到了信息(HTML代码),解析成图片文字;
两者间断开连接。
一次完整的请求就此完成。
问:浏览器能发送HTTP协议,所以HTTP协议一定要用连起来发送吗?
NO,HTTP既然是一种协议,只要能满足这种协议,什么工具都可发。
重要性和主要特点
很多做Web开发的同学完全不理解HTTP协议,包括前端与后端;
对许多后端同学来说,HTTP协议的method在他们眼中只有get/post两种,HTTP返回只有200/500/401/404;
同样,对于许多前端同学来说,关于HTTP前端做的最多的项目就是缓存,他们眼中的缓存可能就是catch-control的配置,而实际上缓存远远不止这些,有代理服务器缓存、客户端缓存、缓存验证可用性;这些功能许多人可能闻所未闻。
有人总结了一下,出现这种情况的原因是:
HTTP作为Web开发中最基本的内容,所有Web开发的数据传输、内容传输都是通过HTTP协议进行的;
但在当今的Web开发中,大家一般很难有机会得知:入门必须要从HTTP协议开始(且若没有计算机基础,HTTP协议也比较难以理解)
所以许多初学者就直接上手框架了,或者前端同学就直接奔向HTML CSS JS了;框架会帮大家处理好大部分内容,框架也会帮助优化上线,所以大家会忽视掉存在的问题,失去接触HTTP协议的机会。
HTTP协议真的非常重要!!!:
前端所有静态资源加载和数据加载都要通过HTTP协议发送;
后端做出来的服务内容,送至前端或移动端APP客户端,也要通过HTTP发送;
面试时,作为后端、前端、客户端中高端从业者,不可能不被问到HTTP协议,且要深入理解他。
一些简单的例子:
- 输入URL打开网页
- 前端AJAX获取数据
- HTML中img标签加载图片(浏览器和服务器如何交互,其中什么内容会影响传输效率)
- Catch-Control中大家都知道max-age=100;但很多人不知道可通过设置public/private来空值只可在客户端。代理服务器缓存;
must-revalidate
:缓存过期后必须在服务端验证过才能继续使用缓存;设置no-catch
no-store
可控制是否使用缓存。 - 验证缓存:缓存存储在客户端,客户端不知道服务端是否有改变这份数据,需要进行缓存验证:(1).
last-modified
配合if-modified-since
;或(2).etag
配合if-none-match
也很有用;
缓存
是Web服务中对性能提升最大的一环,深入理解HTTP缓存对于前后端都非常重要,当然HTTP也不止缓存;
Content-Typr``Content-Encoding
等用来约束数据类型;
Cookie
保持会话信息;
CORS
实现跨域并保持安全性限制;
通过了解其中的步骤,可以针对关键点进行性能优化。
学完HTTP后:
后端:能打造性能更好的HTTP服务;
前端:更好使用HTTP特性帮助开发;
前后端的协作主要来自于HTTP协议,提高沟通效率;
网络协议分层
HTTP三次握手
URI URL URN
之所以有这些区别:为了识别互联网上一个固定位置资源所在的地方
URI:包括URL URN:Uniform Resource Identifier 统一资源标志符
URL:Uniform Resource Locator 统一资源定位器
URN:永久统一资源定位赋 很少用
URL中,若资源搬了家,旧URL就会返回404;但是URN不受资源搬前影响,即使搬来搬去也能通过这一条URN访问到:在资源移动后还能被找到,但目前还没成熟的使用方案。
HTTP报文
首行:
Cookie和Session
Cookie是在服务端返回数据时,通过Set-Cookie
这个Header保存在浏览器中的内容;
浏览器下次在访问同域的请求时会带上此Cookie;
所以Cookie可帮助确认使用者是该用户。
Cookie使用键值对形式保存;
max-age
expires
设置过期时间;
Secure
只在HTTPS请求时发送;(HTTP无)
HTTPONLY
无法通过 document.cookie
访问(JavaScript.document.cookie):
(网上有中常见的攻击 - CSRS攻击:在网页中注入脚本或URL引导用户访问攻击者服务器,攻击者可以获得用户Cookie,泄露个人信息)
重点【HTTP Request】
- 提问:最常用的两种请求?
GET和POST;
GET:请求获取由Request-URI(URL)所标识的资源;
POST:在Request-URI所标识的资源后附加新的内容;
(说URI和URL本质上没区别)
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:
请求行(request line)、请求头部(header)、空行和请求数据4个部分组成。
请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本。
Get请求例子,在Terminal中使用Charles抓取的request:
Control+中括号,回车,调成回响模式,可即使返回响应信息(WIN下)
———————————————————————————————————————————————
HTTP结构:请求报文+响应报文
———————————————————————————————————————————————
1.请求行:①请求方法 / ②URL 路径 / ③协议版本(2018年最主流版本是1.1)
请 2.请求头 Request Header:附加的,需要服务器了解的信息(比如服务器需要捕捉cookie)
求 3.(空行,必有!)
4.请求体:即参数(随便写不写;GET请求没有请求体,因为它的参数写在URL后面;POST写在请求体中)
——————(空行)——————————————————————————————————
1.响应行:①协议版本 / ②状态码 / ③状态文字
2.响应头 Response Header:key:value (即键值对)
响 key:value
应 content-length:(重要)主体的长度
3.(空行,必有!)
4.主体
———————————————————————————————————————————————
GET http://39.108.136.60:8380/app/login/html HTTP/1.1 //请求行
Host: 39.108.136.60:8380 //请求头
Connection:keep-alive
Pragma:no-cache
Cache-Control:no-cache
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,like Gecko)Chrome/70.0.3538.67 Safari/537.36
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 //接受html,于是返回html
Accept-Encoding:gzip,deflate //接受的内容编码
Accept-Language:zh-CN,zh;q=0.9 //接受的语言:中文简体
//空行
HTTP/1.1 200 OK //响应行:协议版本 状态码 状态文字
Server:Apache-Cotote/1.1
Accept-Ranges:bytes
ETag:W/"3431-1541066272000"
Last-Modified:Thu,01 Nov 2018 06:21:07 GMT //资源最后修改时间
Content-Type:text/html;charset-UTF-8 //字符集
Content-Length:3431 //内容长度
Date:Wed,21 Nov 2018 06:21:07 GMT
<!DOCTYPE html PUBLIC...
hello //空一行加「hello」
常见的请求头 Request Header:(了解即可,不需要背)
HTTP状态码
1XX:中间状态,一般都看不到
2XX:成功,如200
3XX:如304
4XX:如404
5XX:如500
响应头:
重要的是:
Set-Cookie:设计接口的安全(接口自动化时需要)
Cointent-Type:关注资源返回是否正常
Location:
Connection:Keep-Alive 是保持tcp不关闭;不是HTTP的,因为他是无状态的。
请求:
第一部分:请求行,用来说明请求类型,要访问的资源以及所使用的HTTP版本.
GET说明请求类型为GET,上式分说明使用的是HTTP1.1版本。
分成:
1.请求方法;(区分大小写):GET / POST / PUT / DELETE / TRACE / OPTIONS
2.请求路径;就是URL的一部分
3.所用的协议;目前一般是HTTP/1.1(0.9和1.0基本不用了)
第二部分:请求头部,紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息
从第二行起为请求头部,HOST将指出请求的目的地.User-Agent,服务器端和客户端脚本都能访问它,它是浏览器类型检测逻辑的重要基础.该信息由你的浏览器来定义,并且在每个请求中自动发送等等
第三部分:空行,请求头部后面的空行是必须的
即使第四部分的请求数据为空,也必须有空行。
第四部分:请求数据也叫主体,可以添加任意的其他数据。(可为空)
换做POST方法试试:
POST请求例子,使用Charles抓取的request:
POST /0606/02.php HTTP/1.1
Host:localhost
Content-Length:23
//空一行
User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Content-Type:application/x-www-form-urlencoded
Connection: Keep-Alive
name=Professional%20Ajax&publisher=Wiley
第一部分:请求行,第一行明了是post请求,以及http1.1版本。
第二部分:请求头部,第二行至第六行。
第三部分:空行,第七行的空行。
第四部分:请求数据,第八行。
重点【HTTP Response】
一般情况下,服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息。
HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
例子
HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8
<html>
<head></head>
<body>
<!--body goes here-->
</body>
</html>
**第一部分:**状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成。
第一行为状态行,(HTTP/1.1)表明HTTP版本为1.1版本,状态码为200,状态消息为(ok)
**第二部分:**消息报头,用来说明客户端要使用的一些附加信息
第二行和第三行为消息报头,
Date:生成响应的日期和时间;Content-Type:指定了MIME类型的HTML(text/html),编码类型是UTF-8
**第三部分:**空行,消息报头后面的空行是必须的
**第四部分:**响应正文,服务器返回给客户端的文本信息。
空行后面的html部分为响应正文。
HTTP之状态码
状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:
1xx:指示信息–表示请求已接收,继续处理
2xx:成功–表示请求已被成功接收、理解、接受
3xx:重定向–要完成请求必须进行更进一步的操作
4xx:客户端错误–请求有语法错误或请求无法实现
5xx:服务器端错误–服务器未能实现合法的请求
常见状态码:
200 OK //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
更多状态码http://www.runoob.com/http/http-status-codes.html
HTTP请求方法
根据HTTP标准,HTTP请求可以使用多种请求方法。
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
GET和POST最常用;RESTful API中还用PUT和DELETE较多。
- GET 请求指定的页面信息,并返回实体主体。 //请求查看一个淘宝商品信息
- POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 //登录时提交用户名和密码(GET亦可,但要做加密处理)
- HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头。
- PUT 替换资源,从客户端向服务器传送的数据取代指定的文档的内容。
- DELETE 请求服务器删除指定的页面。
- CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
- OPTIONS 允许客户端查看服务器的性能。
- TRACE 回显服务器收到的请求,主要用于测试或诊断。
HTTP工作原理
HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
以下是 HTTP 请求/响应的步骤:
1、客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如,http://www.oakcms.cn。
2、发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
3、服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
4、释放连接TCP连接
若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
5、客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
例如:在浏览器地址栏键入URL,按下回车之后会经历以下流程:
1、浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
2、解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;
3、浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
4、服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
5、释放 TCP连接;
6、浏览器将该 html 文本并显示内容;
GET和POST请求的区别
GET请求
GET /books/?sex=man&name=Professional HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive
注意最后一行是空行
POST请求
POST / HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
Connection: Keep-Alive
name=Professional%20Ajax&publisher=Wiley
1、GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,多个参数用&连接;例 如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0 %E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如: %E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。
POST提交:把提交的数据放置在是HTTP包的包体中。上文示例中红色字体标明的就是实际的传输数据
因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变
2、传输数据的大小:首先声明:HTTP协议没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。
而在实际开发中存在的限制主要有:
GET:特定浏览器和服务器对URL长度有限制,例如 IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系 统的支持。
因此对于GET提交时,传输数据就会受到URL长度的 限制。
POST:由于不是通过URL传值,理论上数据不受 限。但实际各个WEB服务器会规定对post提交数据大小进行限制,Apache、IIS6都有各自的配置。
3、安全性
POST的安全性要比GET的安全性高。比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为(1)登录页面有可能被浏览器缓存;(2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了,除此之外,使用GET提交数据还可能会造成Cross-site request forgery攻击
4、Http get,post,soap协议都是在http上运行的
(1)get:请求参数是作为一个key/value对的序列(查询字符串)附加到URL上的
查询字符串的长度受到web浏览器和web服务器的限制(如IE最多支持2048个字符),不适合传输大型数据集同时,它很不安全
(2)post:请求参数是在http标题的一个不同部分(名为entity body)传输的,这一部分用来传输表单信息,因此必须将Content-type设置为:application/x-www-form- urlencoded。post设计用来支持web窗体上的用户字段,其参数也是作为key/value对传输。
但是:它不支持复杂数据类型,因为post没有定义传输数据结构的语义和规则。
(3)soap:是http post的一个专用版本,遵循一种特殊的xml消息格式。Content-type设置为: text/xml 任何数据都可以xml化。
Http协议定义了很多与服务器交互的方法,最基本的有4种,分别是GET,POST,PUT,DELETE. 一个URL地址用于描述一个网络上的资源,而HTTP中的GET, POST, PUT, DELETE就对应着对这个资源的查,改,增,删4个操作。 我们最常见的就是GET和POST了。GET一般用于获取/查询资源信息,而POST一般用于更新资源信息.
我们看看GET和POST的区别
-
GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的Body中.
-
GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制.
-
GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值。
-
GET方式提交数据,会带来安全问题,比如一个登录页面,通过GET方式提交数据时,用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码.
抓HTTP细节操作
因为HTTP是目前移动互联网最主流的协议,打开任何一个网页,或桌面软件,都可能发生HTTP请求。
用FIDDER软件抓一个请求下来观察(此软件不是学习重点),他作为一个代理可以监听。
保存的日志格式是超文本,除了上文所写「重要!HTTP格式之请求消息Request」,下面还有HTML文档。