一、什么是web应用
web(World Wide Web)即全球广域网,也称为万维网,它是基于超文本和http的、全球性的、动态交互的、跨平台的建立在internet上的一种分布式图形信息系统,也是一种网络服务
简单来说就是可以通过浏览器来访问的应用程序,web最大的好处就是访问简易,用户只需要有浏览器即可,不需要额外的软件。这也称为B/S架构,即浏览器/服务器架构(Browser/Server)。其本质是socket间通信:浏览器为socket客户端,服务器是socket服务端
1、web开发的阶段
-
web1.0阶段
- 简单快捷的早起版本,主要以静态web页面、CGI、ASP/JSP/PHP等
- 好处就是简单快捷,本地起一个 Tomcat 或 Apache 就能开发,后续因为Service 越来越多,调用关系变复杂,前端搭建本地环境不再是一件简单的事。考虑团队协作,往往会考虑搭建集中式的开发服务器来解决。这种解决方案对编译型的后端开发来说也许还好,但对前端开发来说并不友好
-
后端为主的MVC时代
- 为了降低复杂度,以后端为出发点,有了 Web Server 层的架构升级,比如 Structs、Spring MVC 等,这是后端的 MVC 时代。
-
Ajax的SPA时代(web2.0)
- CDN 开始大量用于静态资源存储,于是出现了 JavaScript 王者归来的 SPA (Single Page Application 单页面应用)时代。web2.0从此以Ajax概念为契机诞生
-
前端为主的MV*时代
- 为了降低前端开发的复杂度,涌入了大量框架,这些框架总的原则是先按类型分层,比如 Templates、Controllers、Models,然后再在层内做切分
-
web3.0
- .....
2、web的优点
- 开发成本低,好维护、跨平台
- 网站可以根据不同的终端设备进行调整,不需要为不同设备开发不同版本的网站
- 客户端友好
- 只需要客户端有一个浏览器即可,不会额外安装其他软件
- 无需客户端做额外维护操作(更新)
- 几乎所有维护操作都在服务端完成
3、web的缺点
- 依赖于网络,当连接出现问题,应用将无法
- 渲染性能差
- 依赖提供商
- 完全依赖于web提供商,如果提供商倒闭,那么应用将完全无法访问,无法做到像传统安装的软件,即使提供商倒闭,也可以继续使用,无非是无法得到更新和维护
- 客户侧可控性弱
- 提供商如果要推行新版,那么意味着客户仅能使用提供的新版,而不存在客户侧自主选择是否要升级应用版本
- 隐私性弱
- web完全依赖于网络,想比于本地一些应用,理论上提供商可以获取用户所有的行为,可能存在隐患
二、基于SOCKET的web应用
# main.py
import socket
def server_run():
s = socket.socket()
s.bind(('127.0.0.1', 8080))
s.listen(5)
while True:
conn, addr = s.accept()
recv_data = conn.recv(1024)
print(recv_data)
"""
# 1 直接在send里写,发送给客户端
conn.send(
b'HTTP/1.1 200 OK\r\n\r\n<h1>hello web</h1>'
b'<img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"></img>')
"""
"""
# 2 打开一个html文件,发送给客户端
with open('index.html', 'r', encoding='utf-8') as f:
data = f.read()
conn.send(('HTTP/1.1 200 OK\r\n\r\n%s' % data).encode('utf-8'))
"""
# 3 动态网页,字符串替换
import time
now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
print(now)
with open('index.html', 'r', encoding='utf-8') as f:
data = f.read()
data = data.replace('localtime', now)
conn.send(('HTTP/1.1 200 OK\r\n\r\n%s' % data).encode('utf-8'))
conn.close()
if __name__ == '__main__':
server_run()
<!--index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>localtime</h1>
<img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"></img>
</body>
</html>
三、基于socket简易web框架
web框架的3个核心功能
- 收发消息(socket功能)
- 根据用户不同路径执行不同的函数
- 从响应信息构造返回或从htlm文件中读取内容,并完成字符串的替换
python中比较主流的框架:Django、Flask、Tornado
# main.py
import socket
def indexes(url):
with open("index.html", "r", encoding="utf-8") as f:
rd = f.read()
rd = rd.replace("$@index$@", "首页")
return bytes(rd, encoding="utf-8")
def tests(url):
with open("test.html", "r", encoding="utf-8") as f:
rd = f.read()
rd = rd.replace("$@test$@", "测试")
return bytes(rd, encoding="utf-8")
def fun404(url):
ret = "<h1>not found!</h1>"
return bytes(ret, encoding="utf-8")
# 建立url与函数名的对应关系
url_func = [
("/index/", indexes),
("/test/", tests)
]
def run():
sk = socket.socket()
sk.bind(("127.0.0.1", 8000))
sk.listen()
while True:
conn, addr = sk.accept()
data = conn.recv(1024)
if not data:
continue
# 获取请求路径信息
data_str = str(data)
print(data_str)
line = data_str.split("\r\n")
print(line)
url = line[0].split()[1]
# url_func对应关系,确定反馈信息并反馈
conn.send(b"HTTP/1.1 200 OK\r\n\r\n")
func = None
for i in url_func:
if i[0] == url:
func = i[1]
break
if not func:
func = fun404
rep = func(url)
conn.send(rep)
conn.close()
if __name__ == '__main__':
run()
<!--index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>localtime</h1>
<img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"></img>
</body>
</html>
<!--test.html -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>test页面</title>
</head>
<body>
<h1>$@index$@</h1>
</body>
</html>