HTTP协议是超文本传输协议,是浏览器和服务器之间的一种通讯协议,该协议是W3C负责制定的,其实本质上就是数据传送格式提前制定好了。
浏览器和服务器都必须按照这种数据格式进行接收和发送。
我们使用的HTTP协议版本号是HTTP1.1。
HTTP协议包括
- 请求协议:从Browser发送到Server的时候采用的数据传送格式
- 请求行:请求方式 URI 协议版本号
- 消息报头
- 空白行:专门用来分离消息报头和请求体的
- 请求体
- 响应协议:从Server发送到Browser的时候采用的教据传送格式
- 状态行:协议版本号 状态码 状态描述信息
- 响应报头
- 空白行:分离响应报头和响应体
- 响应体
1、 请求行:
a) GET(描述该请求采用了什么请求方法),HTTP协议中包含8种请求方法:
- GET 请求获取Request-URI 所标识的资源
- POST 在Request-URI 所标识的资源后附加新的数据
- HEAD 请求获取由Request-URI 所标识的资源的响应消息报头
- PUT 请求服务器存储一个资源,并用Request-URI 作为其标识
- DELETE 请求服务器删除Request-URI 所标识的资源
- TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
- CONNECT 保留将来使用
- OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求
b) URI(请求WEB服务器的资源名称)
(一) URI:统一资源标识符(代表这个资源的名称),如:上图中的 /PrjTheHttpProtocol/test?username=admin&userpassword=123
说明:HTTP协议规定GET请求发送数据在URI中发送,格式:uri?name=value&name=value&name=value…..
(二) URL:统一资源定位符(不但代表这个资源的名称,而且通过它还可以找到该资源),如:http://ip:port/URI
c) HTTP1.1(当前使用的HTTP协议版本)
2、 请求报头
a) 告诉web服务器浏览器接收的语言版本
b) 请求web服务器的IP地址和端口号
c) Cookies等信息。
3、 空白行(分割请求报头和请求体的专用行)
4、 请求体(由于当前使用的请求方式是GET请求方式,所以请求体中不传送任何数据)
1、 请求行:
a) 上图采用POST方式发送请求。
b) 上图URI后边没有任何数据,这是因为采用POST方式提交的缘故。
c) HTTP1.1(当前使用的HTTP协议版本)
2、 请求报头(由于请求是POST请求,所以报头中显示:Cache-Control:no-cache)
3、 空白行(分割请求报头和请求体的专用行)
4、 请求体(由于当前使用的请求方式是POST请求方式,所以数据在请求体中发送,并且格式是:name=value&name=value&name=value……)
1、 状态行
a) HTTP1.1 : HTTP协议版本号
b) 200 : 响应状态号
状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
1xx:指示信息--表示请求已接收,继续处理
2xx:成功--表示请求已被成功接收、理解、接受
3xx:重定向--要完成请求必须进行更进一步的操作
4xx:客户端错误--请求有语法错误或请求无法实现
5xx:服务器端错误--服务器未能实现合法的请求
常见状态代码、状态描述、说明:
200 OK 客户端请求成功
400 Bad Request 客户端请求有语法错误,不能被服务器所理解
401 Unauthorized 请求未经授权
403 Forbidden 服务器收到请求,但是拒绝提供服务,权限不够(如果访问a目录,但是a目录设置不可见)
404 Not Found 请求资源不存在
500 Internal Server Error 服务器发生不可预期的错误,服务器内部错误(代码有误)
503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后, 可能恢复正常
405 浏览器客户端发送的请求和底层的方法doPost/doGet不一致导致的。
300/301 页面重定向(跳转)
c) OK : 对响应结果的描述
2、 响应报头
a) WEB服务器版本信息
b) 内容类型以及字符编码方式
c) 内容长度,响应回来的总字符数
d) 响应时间
e) Cookies等信息。
3、 空白行(分割响应报头和响应正文的专用行)
4、 响应正文(从WEB服务器端响应回来的HTML代码)
Firefox
HttpWatch
GET和POST
什么情况下浏览器发送的请求是GET请求?什么情况下浏览器发送的请求是POST请求?
只有当使用表单forms并且将form标签的method属性设置为method="post"才是POST请求方式,其余剩下所有的请求方式都是基于GET方式的。
GET方式
<form action="/Servlet-08/system/login">
username<input type="text" name="username"><br> password<input
type="password" name="userpswd"><br> <input
type="submit" value="login">
</form>
GET方式
<form action="/Servlet-08/system/login" method="get">
username<input type="text" name="username"><br> password<input
type="password" name="userpswd"><br> <input
type="submit" value="login">
</form>
POST方式
<form action="/Servlet-08/system/login" method="post">
username<input type="text" name="username"><br> password<input
type="password" name="userpswd"><br> <input
type="submit" value="login">
</form>
GET请求和POST请求有什么区别?
- GET请求在请求行上提交教据,格式:uni?name=value&name=value&name=value.... 这种提交方式最终提交的教据会显示到浏览器的地址栏上
- POST请求在请求体中提交数据,相对安全,提交格式:name=value&name=value&name=value... 这种提交方式最终不会再浏览器地址栏上显示
- POST请求在请求体中提交数据,所以POST请求提交的数据没有长度的限制【POST可以提交大数据】
- GET请求在请求行上提交数据,所以GET请求提交的教据长度有限制
- GET诸求只能提交享符串数据,POST诸求可以提交任何类型的数据。包括视频...,所以文件上传必须使用POST请求提交。
- GET请求的最终结果会被浏览器缓存收纳。而POST请求最终的结果不会被浏览器缓存。
GET请求和POST请求应当如何选择使用?
- 有敏感数据,必须使用POST
- 传送教据不是普通字符串,必须使用POST
- 传送的数据非常多,使用POST
- 这个请求是为了修改服务器端资源,使用POST
- GET请求多数情况下是从服务器中读取资源。这个读取的资源在短时间之内是不会发生变化的。所以GET请求最终的结果浏览器缓存起来了。
- POST请求是为了修改服务器端的资源,而每一次修改结果都是不同的s最终结果没有必要被浏览器缓存。
服务器将资源缓存之后,缓存的资源是和某个特定的路径绑定在一起的,只要浏览器再发送这个相同的请求路径,这个时候回去缓存中获取资源,不再访问服务器,以这种方式降低服务器的压力,提高用户体验。但是有的时候,我们不希望走缓存,希望每一个都访问服务器,可以在请求路径后面添加时间戳,例如
http://ip:proot/oa/system/logout?timestamp=12313113123
JS怎么获取毫秒:new Date().getTime();
HTTP请求的两种方式,GET和POST请求的表面形式上的区别:
- GET请求通过URL(请求行)提交数据,在URL中可以看到所传参数。POST通过“请求体”传递数据,参数不会在url中显示 。
- GET请求提交的数据有长度限制(1024或2048),POST请求没有限制(或限制80KB)。
- GET请求返回的内容可以被浏览器缓存起来。而每次提交的POST,浏览器在你按下F5的时候会跳出确认框,浏览器不会缓存POST请求返回的内容。
以上描述都是GET,POST两者区别表现形式,是浏览器对这两种请求的处理方式。作为Web开发人员,更应该看清的是它们的本质区别是什么HTTP协议是这样解释GET和POST的:GET请求不应该做读取数据之外的事情(原文:Requests using GET SHOULD NOT have the significance of taking an action other than retrieval)。而如果一个请求,修改了服务器资源或者使用了服务器资源(如发邮件,使用打印机等),那么应当使用POST。所以,GET和POST的本质区别是使用场景的区别,简单的说,GET是只读,POST是写。浏览器对两种请求的不同处理方式也是基于这两个不同的场景:
- GET:查询往往需要的上传的数据量比较小,查询参数也往往不需要保密,所以放在url里比较高效。HTTP协议要求同一URL的多个请求应该返回同样的结果,所以浏览器可以把返回结果缓存起来,以提高性能。至于参数长度的限制,这个是和浏览器url的长度限制相关的,1024也好,2048也好,其实没有太大的意义,参数超长往往是错误使用GET方法的结果。
- POST:修改数据需要支持大数据量表单的提交,数据也常常包含用户的私人信息,所以数据放在请求的消息体中传递。相同的POST请求可能会对服务器端产生不同的影响,比如两次POST可能创建两条不同的数据,所以对POST返回结果的缓存是没有意义的。
用GET,还是用POST?
如果回答“因为POST的参数长度不受限制,所以我用POST”,就有点本末倒置了。两者之间如何选择,首先要看是不是修改或者使用了服
务器资源,其次要看请求或者响应中的数据是不是包含了敏感信息,如果是,那么应该选择POST,同时处于安全性的考虑,服务器端应该
只接受POST,拒绝GET。比如数据的增加和修改,认证信息的提交,是一定要用POST的。如果只是简单查询,用GET就可以了。
POST请求是不是比GET请求更安全?
有人说“POST比GET安全,因为GET的参数都明文写在url上了”,从个人信息安全的角度上说,这句话是对的,但这种安全机制是“防君
子不防小人”的,有各种工具能够获取POST请求的数据。如前面所说,两者有截然不同的使用场景,如果是该用POST的地方用了GET,
又说GET不安全,那GET也太冤枉了。其实,HTTP协议中提到GET是安全的方法(safe method),其意思是说GET方法不会改变服务器
端数据,所以不会产生副作用。这是建立在Web开发人员正确使用GET方法的基础上的,如果修改数据的请求却使用了GET方法,显然
是非常危险的。
GET与POST的误用有什么危害?
应该使用GET的地方用了POST:性能受损,浏览器不会缓存。
应该使用POST的地方用了GET:每一个这样的地方都是一个漏洞,有可能被黑客利用。如果是一个对安全要求很高的网站,一定不要忽视。
不仅仅是在前端要正确的使用GET和POST,同时还需要后端代码的支持,比如后端应当在需要POST请求的时候拒绝GET请求,从而切
断黑客利用GET请求攻击的途径,更高级别的,还需要对POST请求进行过滤,以确保所有的POST请求都来自可信任的地址。
如何判断当前请求是GET请求还是POST请求?
- 在浏览器地址栏上直接编写URL提交的请求一定是GET请求。
- 使用热链接向服务器发送的请求一定是GET请求。
- 使用form表单提交数据的时候,如果method属性没有编写,或者method属性值被指定是GET,这样发送的请求属于GET请求。
- 使用form表单提交数据的时候,如果method属性值被手动指定为POST,那么该请求属于POST请求。
思考:我们在做javaweb开发的时候所有的Servlet都要继承HttpServlet类,并且负责重写doGet和doPost方法,假设当前请求是POST请求,而没有重写doPost方法为什么会出现以下异常?
底层是doPost方法表明希望客户端发送的请求是POST请求,如果此时发送的请求是GET请求,则会执行HtttpServlet类中的doGet方法,这样这个方法会报错(上面就是错误)。
该用POST的时候,java的Servlet服务器端代码进行了控制,客户端只能发送POST请求,不嫩发送GET,你只要发GET就报错。
记住:不要随意的编写doPost和doGet,是POST就编写doPost方法,是GET就编写doGet方法。在重写doGet方法和doPost方法的时候一定记住不要再调用super.doGet或者super.doPost等方法。
HTTP状态码404、500
在webapp中常见的错误代码:
- 404 - Not Found【资源未找到:请求的资源路径写错了】
- 500 - Server Inner Error【服务器内部错误〉这种情况一般都是java程序出现异常】
404和500是HTTP协议状态码
以上的这些状态号是W3C制定的,所有浏览器和服务器都必须遵守
正常响应的HTTP协议状态码:200【OK】
在一些错误发生之后统一进行错误的处理,可以在web.xml文件中做以下配置:
<error-page> <error-code>404</error-code> <location>/error/error.html</location> </error-page> <error-page> <error-code>500</error-code> <location>/error/error.html</location> </error-page>
路径总结(三类)
- 第一类:以/开始,加wsbapp名称
- 第二类:以/开始,不加webapp名称
- 第三类:不以/开始,也不需要加webapp名称