web指的是网络,web应用开发指的是基于网络的应用程序开发。
Web应用开发分为web前端开发和web后端开发。
Web前端开发:我们可以简单的理解为开发一些网页。
Web后端开发:写一些逻辑判断程序。
当用户发出请求给我们写的程序,程序根据用户的请求做出相应的判断,然后返回给客户相应的内容。
两个程序之间通讯的应用大致可以分为两种:
第一种是应用类程序:qq、微信、网盘、优酷这一类是属于需要安装的桌面应用
第二种是web类程序:用户只需要浏览器即可访问程序。常见的web类应用程序
比如百度、知乎、CSDN等使用浏览器访问就可以直接使用。
不管是应用类程序还是web类程序,这些应用的本质其实都是两个程序之间的通讯。
而这两个分类又对应了两个软件开发的架构~
C/S即:Client与Server ,中文意思:客户端与服务器端架构。
这里的客户端一般泛指客户端应用程序exe,程序需要先安装后,才能运行在用户的电脑上,对用户的电脑操作系统环境依赖较大。
B/S即:Browser与Server,中文意思:浏览器端与服务器端架构。
只需在浏览器上通过HTTP去请求服务器端相关的资源(网页资源)。
执行流程:
浏览器发出一次请求给服务端,服务端通过逻辑判断把相应的数据发送给客户端。
依次执行上面的流程。
我们可以这样理解:所有的Web应用框架本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端。 一些常用框架(Django、Tornado、Flash)是对socket服务端进行的封装,使得基础功能更加完善。
(1)自定义web框架
import socket
server_sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_sk.bind(('127.0.0.1', 9999))
server_sk.listen(128)
while True:
new_sk, addr = server_sk.accept()
content = new_sk.recv(1024)
print('接受到了数据...')
print(content)
# 给浏览器发生内容
new_sk.send(b'HTTP/1.1 200 ok\r\n\r\n') # 设置协议格式
new_sk.send(b'ok')
new_sk.close()
(2)根据不同路径返回不同内容
import socket
server_sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_sk.bind(('127.0.0.1', 9999))
server_sk.listen(128)
while True:
new_sk, addr = server_sk.accept()
content = new_sk.recv(1024)
content = content.decode(encoding='UTF-8')
# print(content)
# 1.根据\r\n 进行切割 获取 请求首行
data = content.split('\r\n')[0] # GET /index HTTP/1.1
# print(data)
# 2.根据空格进行切割,获取路径 /index
data = data.split()[1]
print(data)
new_sk.send(b'HTTP/1.1 200 ok\r\n\r\n')
if data == '/index':
response = b'index'
elif data == '/home':
response = b'home'
else:
response = b'404 not found...'
new_sk.send(response)
new_sk.close()
(3)根据不同路径返回不同内容–函数版
import socket
sever_sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sever_sk.bind(('127.0.0.1', 9999))
sever_sk.listen(128)
# 使用函数
def index(url):
s = '这是{}页面'.format(url)
return s.encode('utf-8')
# 使用函数
def home(url):
s = '这是{}页面'.format(url)
return s.encode('utf-8')
while True:
new_sk, addr = sever_sk.accept()
content = new_sk.recv(1024)
content = content.decode(encoding='utf-8')
data = content.split('\r\n')[0]
data = data.split()[1]
# print(data)
if data == '/index':
response = index(data)
elif data == '/home':
response = home(data)
else:
response = b'404 not found...'
new_sk.send(b'HTTP/1.1 200 OK\r\n')
# 如果浏览器乱码则添加相应头信息。
new_sk.send(b'Content-Type: text/html;charset=utf-8\r\n')
new_sk.send(b'\r\n')
new_sk.send(response)
new_sk.close()
(4)根据不同的路径返回不同的内容–函数进阶版
import socket
sever_sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sever_sk.bind(('127.0.0.1', 9999))
sever_sk.listen(128)
def index(url):
s = '这是{}页面'.format(url)
return s.encode('utf-8')
def home(url):
s = '这是{}页面'.format(url)
return s.encode('utf-8')
# 1.定义一个url和执行函数对应关系的列表
url_func_lst = [
('/index', index),
('/home', home)
]
while True:
new_sk, addr = sever_sk.accept()
content = new_sk.recv(1024)
content = content.decode(encoding='utf-8')
data = content.split('\r\n')[0]
url = data.split()[1]
# 2.定义一个变量来接受对应的函数名称
func = None
# 3.变量列表,查收是否有对应的url
for url_func in url_func_lst:
if url_func[0] == url:
func = url_func[1]
if func:
response = func(url)
else:
response = b'404 not found...'
new_sk.send(b'HTTP/1.1 200 OK\r\n')
new_sk.send(b'Content-Type: text/html;charset=utf-8\r\n')
new_sk.send(b'\r\n')
new_sk.send(response)
new_sk.close()
(5)返回具体的HTML文件
import socket
sever_sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sever_sk.bind(('127.0.0.1', 9999))
sever_sk.listen(128)
# 1.读取 index.html中的内容
def index(url):
with open('index.html', mode='rb') as f:
data = f.read()
return data
# 2.读取 home.html中的内容
def home(url):
with open('home.html', mode='rb') as f:
data = f.read()
return data
url_func_lst = [
('/index', index),
('/home', home)
]
while True:
new_sk, addr = sever_sk.accept()
content = new_sk.recv(1024)
content = content.decode(encoding='utf-8')
data = content.split('\r\n')[0]
url = data.split()[1]
func = None
for url_func in url_func_lst:
if url_func[0] == url:
func = url_func[1]
if func:
response = func(url)
else:
response = b'404 not found...'
new_sk.send(b'HTTP/1.1 200 OK\r\n')
new_sk.send(b'Content-Type: text/html;charset=utf-8\r\n')
new_sk.send(b'\r\n')
new_sk.send(response)
new_sk.close()
(6)让网页动起来
# 1.导入time模块
import socket, time
sever_sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sever_sk.bind(('127.0.0.1', 9999))
sever_sk.listen(128)
# 2.替换页面中的内容
def index2(url):
with open('index2.html', mode='r', encoding='UTF-8') as f:
data = f.read()
data = data.replace('xxooxx', str(time.time()))
data = bytes(data, encoding='utf-8')
return data
def home(url):
with open('home.html', mode='rb') as f:
data = f.read()
return data
url_func_lst = [
('/index2', index2),
('/home', home)
]
while True:
new_sk, addr = sever_sk.accept()
content = new_sk.recv(1024)
content = content.decode(encoding='utf-8')
data = content.split('\r\n')[0]
url = data.split()[1]
func = None
for url_func in url_func_lst:
if url_func[0] == url:
func = url_func[1]
if func:
response = func(url)
else:
response = b'404 not found...'
new_sk.send(b'HTTP/1.1 200 OK\r\n')
new_sk.send(b'Content-Type: text/html;charset=utf-8\r\n')
new_sk.send(b'\r\n')
new_sk.send(response)
new_sk.close()
(7)总结
总结
1.web框架的本质:socket 服务端 与浏览器的通讯。
2.socket 服务端功能可以划分为3部分: