# web初识:
## 软件开发架构:
c/s架构:客户端服务端架构
b/s架构:浏览器与服务端
本质:b/s架构其实也是c/s架构
## 什么是web应用:
Web应用程序是一种可以通过Web访问的应用程序。Web应用程序的一个最大好处就是用户很容易访问应用程序。
用户只要有浏览器即可,不需要再安装其他软件。
web应用程序举例:淘宝、天猫、新浪、搜狐
### web程序的优点:
- 网络应用程序强调浏览器的适用性。如果浏览器方没有提供特定的功能,或者弃用特定的平台或操作系统版本(导致不适用),就会影响大量用户;
- 网络应用依靠互联网远程服务器端的应用文件。因此,当连接出问题时,应用将不能正常使用。
- 许多网络应用程序不是开源的,只能依赖第三方提供的服务,因此不能针对用户定制化、个性化,而且大多数情况下用户不能离线使用,因而损失了很多灵活性;
- 它们完全依赖应用服务商的可及性。如果公司倒闭,服务器停止使用,用户也无法追索以前的资料。对比而看,即使软件制造商倒闭了,传统的安装软件也可以继续运行,尽管不能再更新或有其他用户服务;
- 相似地,提供方公司对软件和其功能有了更大的控制权。只要他们愿意就能为软件添加新特性,即使用户想等bugs先被解决再更新。跳过较差的软件版本也不可能了。公司可以强加不受欢迎的特性给用户,也可以随意减少带宽来削减开支。
- 公司理论上可以检索任何的用户行为。这有可能引起隐私安全问题。
### B/S架构优点
浏览器/服务器架构(Browser/Server,简称B/S)能够很好地应用在广域网上,成为越来越多的企业的选择。浏览器/服务器架构相对于其他几种应用程序体系结构,有如下3方面的优点:
- 这种架构采用Internet上标准的通信协议(通常是TCP/IP协议)作为客户机同服务器通信的协议。这样可以使位于Internet任意位置的人都能够正常访问服务器。对于服务器来说,通过相应的Web服务和数据库服务可以对数据进行处理。对外采用标准的通信协议,以便共享数据。
- 在服务器上对数据进行处理,就处理的结果生成网页,以方便客户端直接下载。
- 在客户机上对数据的处理被进一步简化,将浏览器作为客户端的应用程序,以实现对数据的显示。不再需要为客户端单独编写和安装其他类型的应用程序。这样,在客户端只需要安装一套内置浏览器的操作系统,直接安装一套浏览器,就可以实现服务器上数据的访问。而浏览器是计算机的标准设备
**总结一下,本质上:浏览器是一个socket客户端,服务器是一个socket服务端**
### 基于socket写一个web应用
```python
import socket
def server_run():
sock = socket.socket()
sock.bind(("127.0.0.1",8888))
sock.listen(5)
while True:
conn,addr = sock.accept()
recv_data=conn.recv(1024)
#1直接在send里写发送的内容,发送到客户端
conn.send(b"HTTP/1.1 200 OK
<h1>hello</h1>")
#2打开html文件发送文件到客户端
with open("index.html","r",encoding="utf-8") as f:
data=f.read()
conn.send(("HTTP/1.1 200 OK
%s"%data).encode("utf-8"))
#3动态网页,字符串替换
import time
now = time.strftime("%Y-%m-%d %X")
print(now)
with open("index.html","r",encoding="utf-8") as f:
data=f.read()
#将读出来的字符串通过替换把时间加到html文件中
data = data.replace("@@@",now)
conn.send(("HTTP/1.1 200 OK
%s"%data).encode("utf-8"))
```
```html
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>@@@</h2>
<img src="https://gss2.bdstatic.com/9fo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike92%2C5%2C5%2C92%2C30/sign=5e3814acf9edab64607f4592965fc4a6/14ce36d3d539b600c0c465d0eb50352ac65cb74b.jpg" alt="">
</body>
</html>
```
手撸一个web框架
```python
import socket
import pymysql
def index(request):
return 'index'
def login(request):
with open("login.html", "r", encoding="utf-8") as f:
data = f.read()
return data
def time(request):
import datetime
now = datetime.datetime.now().strftime("%Y-%m-%d %X")
with open("time.html", "r", encoding="utf-8") as f:
data = f.read()
data = data.replace("@@time@@", now)
return data
def user_list(request):
conn = pymysql.connect(
host="127.0.0.1",
port=3306,
user="root",
password="123",
database="day54",
charset="utf8",
autocommit=True,
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("select id,name,password from user_info")
user_list = cursor.fetchall()
print(user_list)
tr_list = []
for user in user_list:
tr = "<tr><td>%s</td><td>%s</td> <td>%s</td></tr>" % (user["id"], user["name"], user["password"])
tr_list.append(tr)
with open("user_list.html", "r", encoding="utf-8") as f:
data = f.read()
data = data.replace("@@body@@", "".join(tr_list))
return data
def user_list_new(request):
from jinja2 import Template
conn = pymysql.connect(
host="127.0.0.1",
port=3306,
user="root",
password="123",
database='day54',
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute("select id,name,password from user_info;")
user_list = cursor.fetchall()
# for user in user_list:
cursor.close()
conn.close()
print(user_list)
with open("user_list_new.html", "r", encoding="utf-8") as f:
data = f.read()
template = Template(data)
response = template.render(user_list=user_list)
return response
urls = [
("/index", index),
("/login", login),
("/time", time),
("/user_list", user_list),
("/user_list_new", user_list_new),
]
def run():
sock = socket.socket()
sock.bind(("127.0.0.1", 8080))
sock.listen(5)
while True:
conn, port = sock.accept()
# 接收请求信息
data = conn.recv(1024)
print(data)
# data=str(data,encoding='utf-8')
data = data.decode("utf-8")
# b'GET / HTTP/1.1
Host: 127.0.0.1:8080
# Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5944.400 LBBROWSER/10.1.3378.400
Upgrade-Insecure-Requests: 1
# Accept: text//html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
# Accept-Language: zh-CN,zh;q=0.9
'
# 分割每条信息
request_list = data.split("
")
head_list = request_list[0].split("
")
method, url, http = head_list[0].split(' ')
conn.send(b"HTTP/1.1 200 OK
")
print(url)
func_name = None
for u in urls:
if url == u[0]:
func_name = u[1]
break
if func_name:
response = func_name(data)
else:
response = "404 not found"
conn.send(response.encode("utf-8"))
conn.close()
if __name__ == '__main__':
run()
```
```html
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="">
<p>用户名:<input type="text"></p>
<p>密码:<input type="password"></p>
</form>
</body>
</html>
```
```html
```
###### time.html
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
@@time@@
</body>
</html>
```
user_list.html
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
</head>
<body>
<table border="1">
<thead>
<tr>
<th>id</th>
<th>用户名</th>
<th>密码</th>
</tr>
</thead>
<tbody>
@@body@@
</tbody>
</table>
</body>
</html>
```
user_list_new.html
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
</head>
<body>
<table border="1">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>password</th>
</tr>
</thead>
<tbody>
{% for user in user_list%}
<tr>
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.password}}</td>
</tr>
{%endfor%}
</tbody>
</table>
</body>
</html>
```