HTTP协议及Web静态服务器-显示需要的页面代码

HTTP协议简介

  1. 使用谷歌/火狐浏览器分析
    在Web应用中,服务器把网页传给浏览器,实际上就是把网页的HTML代码发送给浏览器,让浏览器显示出来。而浏览器和服务器之间的传输协议是HTTP,所以:
  • HTML是一种用来定义网页的文本,会HTML,就可以编写网页;

  • HTTP是在网络上传输HTML的协议,用于浏览器和服务器的通信。

Chrome浏览器提供了一套完整地调试工具,非常适合Web开发。

安装好Chrome浏览器后,打开Chrome,在菜单中选择“视图”,“开发者”,“开发者工具”,就可以显示开发者工具:
在这里插入图片描述
说明
Elements显示网页的结构
Network显示浏览器和服务器的通信
我们点Network,确保第一个小红灯亮着,Chrome就会记录所有浏览器和服务器之间的通信:

说明
Elements显示网页的结构
Network显示浏览器和服务器的通信
我们点Network,确保第一个小红灯亮着,Chrome就会记录所有浏览器和服务器之间的通信:
在这里插入图片描述
2. http协议的分析
当我们在地址栏输入www.sina.com时,浏览器将显示新浪的首页。在这个过程中,浏览器都干了哪些事情呢?通过Network的记录,我们就可以知道。在Network中,找到www.sina.com那条记录,点击,右侧将显示Request Headers,点击右侧的view source,我们就可以看到浏览器发给新浪服务器的请求:

2.1 浏览器请求
在这里插入图片描述
在这里插入图片描述
说明
最主要的头两行分析如下,第一行:

   GET / HTTP/1.1

GET表示一个读取请求,将从服务器获得网页数据,/表示URL的路径,URL总是以/开头,/就表示首页,最后的HTTP/1.1指示采用的HTTP协议版本是1.1。目前HTTP协议的版本就是1.1,但是大部分服务器也支持1.0版本,主要区别在于1.1版本允许多个HTTP请求复用一个TCP连接,以加快传输速度。

从第二行开始,每一行都类似于Xxx: abcdefg:``

Host: www.sina.com

总结

HTTP请求
跟踪了新浪的首页,我们来总结一下HTTP请求的流程:

步骤1:浏览器首先向服务器发送HTTP请求,请求包括:
方法:GET还是POST,GET仅请求资源,POST会附带用户数据;

路径:/full/url/path;

域名:由Host头指定:Host: www.sina.com

以及其他相关的Header;

如果是POST,那么请求还包括一个Body,包含用户数据

步骤2:服务器向浏览器返回HTTP响应,响应包括:

响应代码:200表示成功,3xx表示重定向,4xx表示客户端发送的请求有错误,5xx表示服务器端处理时发生了错误;

响应类型:由Content-Type指定;

以及其他相关的Header;

通常服务器的HTTP响应会携带内容,也就是有一个Body,包含响应的内容,网页的HTML源码就在Body中。

步骤3:如果浏览器还需要继续向服务器请求其他资源,比如图片,就再次发出HTTP请求,重复步骤1、2。

Web采用的HTTP协议采用了非常简单的请求-响应模式,从而大大简化了开发。当我们编写一个页面时,我们只需要在HTTP请求中把HTML发送出去,不需要考虑如何附带图片、视频等,浏览器如果需要请求图片和视频,它会发送另一个HTTP请求,因此,一个HTTP请求只处理一个资源(此时就可以理解为TCP协议中的短连接,每个链接只获取一个资源,如需要多个就需要建立多个链接)

HTTP协议同时具备极强的扩展性,虽然浏览器请求的是http://www.sina.com的首页,但是新浪在HTML中可以链入其他服务器的资源,比如,从而将请求压力分散到各个服务器上,并且,一个站点可以链接到其他站点,无数个站点互相链接起来,就形成了World Wide Web,简称WWW。

Web静态服务器-显示需要的页面

#coding=utf-8
import socket
import re


def client(new_sok):
	"""为这个客户端返回数据"""
	
	# 接受浏览器发送过来的请求,即http请求
	request = new_sok.recv(1024),decode("utf-8)
	# 切割request列表
	request_lines = requse.splitlines()
	# 返回http格式的数据给浏览器
	# 准备发给浏览器的数据---header
	file_name = ""
	ret = re.match(r"[^/]+(/[^ ])*", request_lines[0])
	# 如果正则表达式判断成立
	if ret:
		flie_name = ret.group(1)
		# 如果没有指定访问哪个页面
		if file_name == "/":
			flie_name = "/index.html"
	try:  # 打开文件
		f = open("./html" + file_name, "rb")
	except:  # 如果没有这个文件或者打开失败
		# 返回给浏览器response
		response = "HTTP/1.1 404 NOT FOUND\r\n"
		response += "\r\n"
		response += "404 NOT FOUND"
		new_sok.send(response.encode("utf-8"))
	else:  # 如果打开成功返回给浏览器这个文件内容
		html_content = f.read()
		f.close()
		# 准备发给浏览器的数据---header
		response = "HTTP/1.1 200 OK\r\n"
		response += "\r\n"
		# 准备发给浏览器的数据---body
		new_sok.send(response.encode("utf-8"))
		new_sok.send(html_content)
	# 关闭套接字
	new_sok.close()
	

def main():
	# 创建套接字
	sok = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sok.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
	# 绑定本地信息
	sok.bind("",7890)
	# 变为监听套接字
	sok.listen(128)
	while True:
		# 等待新客户端链接
		new_sok, ulr_ip = sok.accept()
		client(new_sok)
	# 关闭套接字
	sok.close()


if __name__ == "__main__":
	main()
	说明:
	文件必须在当前目录下或者把代码路径改了

猜你喜欢

转载自blog.csdn.net/weixin_44786231/article/details/89318482