资深软件开发工程师,业余马拉松选手。
今天我们访问网站,使用App时,都是基于Web这种Browser/Server模式,简称BS架构,它的特点是,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web页面,并把Web页面展示给用户即可。
Web页面具有极强的交互性。由于Web页面是用HTML编写的,而HTML具备超强的表现力,并且,服务器端升级后,客户端无需任何部署就可以使用到新的版本,因此,BS架构升级非常容易。
在Web应用中,浏览器请求一个URL,服务器就把生成的HTML网页发送给浏览器,而浏览器和服务器之间的传输协议是HTTP,所以:
- HTML是一种用来定义网页的文本,会HTML,就可以编写网页;
- HTTP是在网络上传输HTML的协议,用于浏览器和服务器的通信。
HTTP协议是一个基于TCP协议之上的请求-响应协议,它非常简单,我们先使用Chrome浏览器查看新浪首页,然后选择View - Developer - Inspect Elements就可以看到HTML:
切换到Network,重新加载页面,可以看到浏览器发出的每一个请求和响应:
对于Browser来说,请求页面的流程如下:
- 与服务器建立TCP连接;
- 发送HTTP请求;
- 收取HTTP响应,然后把网页在浏览器中显示出来。
浏览器发送的HTTP请求如下:
其中,第一行表示使用请求获取路径为的资源,并使用协议,从第二行开始,每行都是以形式表示的HTTP头,比较常用的HTTP Header包括:
- Host: 表示请求的主机名,因为一个服务器上可能运行着多个网站,因此,Host表示浏览器正在请求的域名;
- User-Agent: 标识客户端本身,例如Chrome浏览器的标识类似,IE浏览器的标识类似;
- Accept:表示浏览器能接收的资源类型,如,或者表示所有;
- Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页;
- Accept-Encoding:表示浏览器可以支持的压缩类型,例如。
服务器的响应如下:
服务器响应的第一行总是版本号+空格+数字+空格+文本,数字表示响应代码,其中表示成功,表示重定向,表示客户端引发的错误,表示服务器端引发的错误。数字是给程序识别,文本则是给开发者调试使用的。常见的响应代码有:
- 200 OK:表示成功;
- 301 Moved Permanently:表示该URL已经永久重定向;
- 302 Found:表示该URL需要临时重定向;
- 304 Not Modified:表示该资源没有修改,客户端可以使用本地缓存的版本;
- 400 Bad Request:表示客户端发送了一个错误的请求,例如参数无效;
- 401 Unauthorized:表示客户端因为身份未验证而不允许访问该URL;
- 403 Forbidden:表示服务器因为权限问题拒绝了客户端的请求;
- 404 Not Found:表示客户端请求了一个不存在的资源;
- 500 Internal Server Error:表示服务器处理时内部出错,例如因为无法连接数据库;
- 503 Service Unavailable:表示服务器此刻暂时无法处理请求。
从第二行开始,服务器每一行均返回一个HTTP头。服务器经常返回的HTTP Header包括:
- Content-Type:表示该响应内容的类型,例如,;
- Content-Length:表示该响应内容的长度(字节数);
- Content-Encoding:表示该响应压缩算法,例如;
- Cache-Control:指示客户端应如何缓存,例如表示可以最多缓存300秒。
HTTP请求和响应都由HTTP Header和HTTP Body构成,其中HTTP Header每行都以结束。如果遇到两个连续的,那么后面就是HTTP Body。浏览器读取HTTP Body,并根据Header信息中指示的、等解压后显示网页、图像或其他内容。
通常浏览器获取的第一个资源是HTML网页,在网页中,如果嵌入了JavaScript、CSS、图片、视频等其他资源,浏览器会根据资源的URL再次向服务器请求对应的资源。
关于HTTP协议的详细内容,请参考HTTP权威指南一书,或者Mozilla开发者网站。
我们在前面介绍的HTTP编程是以客户端的身份去请求服务器资源。现在,我们需要以服务器的身份响应客户端请求,编写服务器程序来处理客户端请求通常就称之为Web开发。
我们来看一下如何编写HTTP Server。一个HTTP Server本质上是一个TCP服务器,我们先用TCP编程的多线程实现的服务器端框架:
只需要在方法中,用Reader读取HTTP请求,用Writer发送HTTP响应,即可实现一个最简单的HTTP服务器。编写代码如下:
这里的核心代码是,先读取HTTP请求,这里我们只处理的请求。当读取到空行时,表示已读到连续两个,说明请求结束,可以发送响应。发送响应的时候,首先发送响应代码表示一个成功的200响应,使用协议,然后,依次发送Header,发送完Header后,再发送一个空行标识Header结束,紧接着发送HTTP Body,在浏览器输入就可以看到响应页面:
HTTP目前有多个版本,是早期版本,浏览器每次建立TCP连接后,只发送一个HTTP请求并接收一个HTTP响应,然后就关闭TCP连接。由于创建TCP连接本身就需要消耗一定的时间,因此,HTTP 1.1允许浏览器和服务器在同一个TCP连接上反复发送、接收多个HTTP请求和响应,这样就大大提高了传输效率。
我们注意到HTTP协议是一个请求-响应协议,它总是发送一个请求,然后接收一个响应。能不能一次性发送多个请求,然后再接收多个响应呢?HTTP 2.0可以支持浏览器同时发出多个请求,但每个请求需要唯一标识,服务器可以不按请求的顺序返回多个响应,由浏览器自己把收到的响应和请求对应起来。可见,HTTP 2.0进一步提高了传输效率,因为浏览器发出一个请求后,不必等待响应,就可以继续发下一个请求。
HTTP 3.0为了进一步提高速度,将抛弃TCP协议,改为使用无需创建连接的UDP协议,目前HTTP 3.0仍然处于实验阶段。
编写一个简单的HTTP服务器。
下载练习
使用B/S架构时,总是通过HTTP协议实现通信;
Web开发通常是指开发服务器端的Web应用程序。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/java-jiao-cheng/17295.html