JavaWeb学习笔记(六)--HTTP协议

1. HTTP协议简介

1.1 HTTP协议简介

客户端连上web服务器后,若想获得web服务其中的某个web资源,需要遵循一定的通讯格式,HTTP协议用于定义客户端与web服务器的通讯格式。

HTTP是HyperText Transfer Protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义web浏览器和web服务器之间交换数据的过程。

HTTP协议是学习JavaWeb开发的基石,不深入了解HTTP协议,就不能说掌握了web开发,更无法管理和维护一些复杂的web站点。

1.2 HTTP协议版本

HTTP 协议的版本:HTTP/1.0 HTTP/1.1

在HTTP1.0协议中,客户端与web服务器建立连接后只能获取一个web资源。

在HTTP1.1协议中,允许客户端与web服务器建立连接后,在一个连接上获取多个web资源。

2. HTTP请求

2.1 HTTP请求格式

客户端连上服务器后,向服务器请求某个web资源,称之为客户端向服务器发送了一个HTTP请求,一个完整的HTTP请求包括:请求行 、若干消息头、一个空行以及实体内容,如图所示:

2.2 HTTP请求的细节--请求行

请求行中的GET称之为请求方式:

  • 请求方式有:GET、POST、HEAD、OPTIONS、DELETE、TRACE、PUT
  • 常用的有:GET、POST
  • 如果用户没有设置,默认情况下浏览器向服务器发送的都是get请求,例如在浏览器中直接输入地址访问,点解超链接访问等都是get,如果用户想把请求改成post,可以通过更改表单的提交方式实现

不管是GET或POST,都用于向服务器请求某个web资源,这两种方式的区别主要表现在数据传递上:

  • 如请求方式为GET方式,则可以在请求的URL地址后,以?的形式带上交给服务器的数据,多个数据之间以&进行分隔,例如:GET /mail/1.html?name=abc&password=xyz HTTP/1.1。GET方式的特点:在URL地址后面参数限制的,其数据容量通常不能超过1K(不同浏览器不同)
  • 如请求是POST方式,则可以在请求的实体中向服务器发送请求数据。POST方式的特点是:传送数据量无限制

2.3 HTTP请求的细节--消息头

Accept: text/html, image/*    告诉服务器,浏览器可以接收的文件格式
Accept-Charset: UTF-8    告诉服务器,浏览器的编码方式
Accept-Encoding: gizp, compress     告诉服务器,浏览器的压缩方式
Accept-Language: en-us, zh-cn     告诉服务器,浏览器的语言环境
Host: www.baidu.com    告诉服务器,浏览器请求的主机地址
If-Modefied-Since    告诉服务器,浏览器缓存时间,服务器那这个时间和资源更新的时间比较,如果资源更新的时间近,就把最新的数据给浏览器,否则就使用缓存数据
Referer: http://www.baidu.com/index.htm    告诉服务器,当前的请求是从哪个页面点击来的,主要应用时防盗链
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko       告诉服务器,浏览器的客户端环境
Cookie:    请求携带的历史数据(历史登陆的用户名密码什么的)
Connection: close/Keep-Alive     告诉服务器,请求完成后是断开连接还是保持连接

3. HTTP响应

3.1 HTTP响应格式

一个HTTP响应代表服务器向客户端回送的数据,它包括:一个状态行、若干消息头、一个空行以及实体内容,如图所示:

3.2 HTTP响应的细节--状态行

状态行格式: HTTP版本号 状态码 原因描述 

举例:HTTP/1.1 200 OK

状态码用于表示服务器对请求的处理结果,它是一个三位的十进制数。响应状态码分为5类:

分类 含义
1** 表示成功接收请求,需要浏览器继续提交下一次请求才能完成整个处理过程
2** 表示成功接收请求并已完成整个处理过程,常用200
3** 需要进一步的操作以完成请求。例如,请求的资源已经移动到了一个新地址,常用302、307、304
4** 客户端请求有误,常用404
5** 服务器端出现错误,常用500

常见状态码:

状态码 含义
200 请求已成功,请求所希望的响应头或数据体将随此响应返回
302 要求客户端执行临时重定向
401 用户没有权限
404 请求失败,请求所希望得到的资源未被在服务器上发现
500 服务器内部错误,无法完成请求


3.3 HTTP响应细节--常用响应头 

HTTP常用的响应头(HTTP响应的消息头)

Location: http://www.baidu.com/index.html 配合302状态码使用,服务器通过这个头告诉客户机找谁
Server: apache tomcat 服务器通过这个头,告诉浏览器服务器的类型
Content-Encoding: gzip 服务器通过这个头,告诉浏览器数据的压缩格式
Content-Length: 80 服务器通过这个头,告诉浏览器回送数据的长度
Content-Language: zh-cn 服务器通过这个头,告诉浏览器回送数据的语言
Content-Type: text/html; charset=utf-8 服务器通过这个头,告诉浏览器回送数据的类型
Last-Modified: Tue, 11 Jul 2018 18:24:51 GMT 服务器通过这个头,告诉浏览器当前资源最后的缓存时间
Refresh: 1; url=http://www.baidu.com 服务器通过这个头,告诉浏览器隔多长时间刷新一次
Content-Disposition: attachment; filename=aaa.zip 服务器通过这个头,告诉浏览器以下载方式打开数据
Transfer-Encoding: chunked 服务器通过这个头,告诉浏览器数据的传送格式
Set-Cookies: xxx 服务器通过这个头,告诉浏览器cookie信息
Etag:xxxx 缓存相关,服务器根据web资源的内容生成一个唯一的标识符,以Etag方式写回给浏览器,下次访问的时候浏览器带Etag的标识符,服务器会检查对应的web资源的标识符和传过来的是否一样,如果一样直接拿缓存,不一样返回改动后的的数据(可以做到实时更新)
Expires: -1 服务器通过这个头,告诉浏览器把回送的资源缓存多长时间, -1或0表示不缓存
Cache-Control: no-cache  服务器通过这个头,告诉浏览器不要缓存数据(浏览器的种类导致 IE,火狐,Chrome)
Pragma: no-cache  服务器通过这个头,告诉浏览器不要缓存数据(浏览器的种类导致 IE,火狐,Chrome),控制浏览器不缓存时把Expires、Cache-Control、Pragma一起设置

3.4 设置HTTP响应头,控制浏览器的行为

3.4.1 用location和302实现请求重定向

常用于用户登陆成功,跳转到网站首页

 1 public class ServletDemo extends HttpServlet {
 2     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 3 
 4     }
 5 
 6     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 7 
 8         response.setStatus(302);
 9         response.setHeader("location", "1.html");
10     }
11 }

浏览器访问:http://localhost:8080/ServletDemo,会自动跳转到http://localhost:8080/1.html

 3.4.2 设置Content-Encoding,告诉浏览器数据的压缩格式

 1     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 2 
 3         String date = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 4                 + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 5                 + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 6                 + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 7                 +"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 8                 + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
 9         System.out.println("压缩前数据大小:" + date.getBytes().length);
10 
11         ByteArrayOutputStream bout = new ByteArrayOutputStream();
12 
13 
14         GZIPOutputStream gout = new GZIPOutputStream(bout);
15         gout.write(date.getBytes());
16         gout.close();
17 
18         byte[] gzip = bout.toByteArray(); //得到压缩后的数据
19         System.out.println("压缩后的数据大小:" + gzip.length);
20 
21         //通知浏览器数据的压缩格式和大小
22         response.setHeader("Content-Encoding", "gzip");
23         response.setHeader("Content-Length", gzip.length + "");
24         response.getOutputStream().write(gzip);
25     }

打开浏览器F12,查看response信息,以及IDEA中打印的压缩前后数据大小。

3.4.3 设置Content-Type,告诉浏览器数据的类型

数据类型写法可以参考Tomcat中的conf/web.xml文件<mime-mapping>标签:

<mime-mapping>
        <extension>png</extension>                        // 这个是文件的扩展名
        <mime-type>image/png</mime-type>                  //这个是回送给浏览器的文件类型
</mime-mapping>
 1     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 2 
 3         response.setHeader("Content-type", "image/png");
 4         InputStream in = this.getServletContext().getResourceAsStream("3.png");
 5         int len = 0;
 6         byte[] buffer = new byte[1024];
 7 
 8         OutputStream out = response.getOutputStream();
 9         while ((len = in.read(buffer)) > 0) {
10             out.write(buffer, 0, len);
11         }
12     }

3.4.4 设置Refresh,告诉浏览器多长时间刷新一次(

常用于数据经常变动页面,比如股票,聊天室

1     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
2 
3         response.setHeader("refresh", "3");
4         Date date = new Date();
5         response.getOutputStream().write(date.toString().getBytes());
6 
7     }

Refresh还可以实现页面重定向,常用的注册成功后,隔几秒跳转到登陆页面或者首页:

1    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
2 
3         response.setHeader("refresh", "3;url='1.html'"); //隔3秒跳转1.html中
4         Date date = new Date();
5         response.getOutputStream().write(date.toString().getBytes());
6 
7     }

3.4.5 设置Content-Disposition: attachment; filename=xxx 告诉浏览器以下载方式打开数据

 1     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 2 
 3         response.setHeader("Content-Disposition", "attachment;filename=test.jpg");
 4 
 5         InputStream in = this.getServletContext().getResourceAsStream("1.jpg");
 6         int len = 0;
 7         byte[] buffer = new byte[1024];
 8 
 9         OutputStream out = response.getOutputStream();
10         while ((len = in.read(buffer)) > 0) {
11             out.write(buffer, 0, len);
12         }
13     }

这块用的IE,Chrome直接就给下载了,没有提示

猜你喜欢

转载自www.cnblogs.com/songchj-bear/p/10388660.html