web应用

Posted ydz1993

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了web应用相关的知识,希望对你有一定的参考价值。

web应用

目录

  • 一:web应用程序是什么
  • 二:基于socket写一个web应用
  • 三:手撸简单web框架

一:web应用程序是什么

Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件。

应用程序的分类

  • C/S模式:C/S是客户端/服务器端程序,也就是说这类程序一般独立运行。

  • B/S模式:B/S就是浏览器端/服务器端应用程序,这类应用程序一般借助IE等浏览器来运行。WEB应用程序一般是B/S模式。

  • 从本质上看:B/S模式也是C/S模式

Web应用程序的优点

  • 网络应用程序不需要任何复杂的“展开”过程,你所需要的只是一个适用的浏览器;
  • 网络应用程序通常耗费很少的用户硬盘空间,或者一点都不耗费;
  • 它们不需要更新,因为所有新的特性都在服务器上执行,从而自动传达到用户端;
  • 网络应用程序和服务器端的网络产品都很容易结合,如email功能和搜索功能;
  • 因为它们在网络浏览器窗口中运行,所以大多数情况下它们是通过跨平台使用的 (例如Windows,Mac,Linux等等)

Web应用程序的缺点

  • 网络应用程序强调浏览器的适用性。如果浏览器方没有提供特定的功能,或者弃用特定的平台或操作系统版本(导致不适用),就会影响大量用户;
  • 网络应用依靠互联网远程服务器端的应用文件。因此,当连接出问题时,应用将不能正常使用。
  • 许多网络应用程序不是开源的,只能依赖第三方提供的服务,因此不能针对用户定制化、个性化,而且大多数情况下用户不能离线使用,因而损失了很多灵活性;
  • 它们完全依赖应用服务商的可及性。如果公司倒闭,服务器停止使用,用户也无法追索以前的资料。对比而看,即使软件制造商倒闭了,传统的安装软件也可以继续运行,尽管不能再更新或有其他用户服务;
  • 相似地,提供方公司对软件和其功能有了更大的控制权。只要他们愿意就能为软件添加新特性,即使用户想等bugs先被解决再更新。跳过较差的软件版本也不可能了。公司可以强加不受欢迎的特性给用户,也可以随意减少带宽来削减开支。
  • 公司理论上可以检索任何的用户行为。这有可能引起隐私安全问题。

B/S架构优点

浏览器/服务器架构(Browser/Server,简称B/S)能够很好地应用在广域网上,成为越来越多的企业的选择。浏览器/服务器架构相对于其他几种应用程序体系结构,有如下3方面的优点:

  • 这种架构采用Internet上标准的通信协议(通常是TCP/IP协议)作为客户机同服务器通信的协议。这样可以使位于Internet任意位置的人都能够正常访问服务器。对于服务器来说,通过相应的Web服务和数据库服务可以对数据进行处理。对外采用标准的通信协议,以便共享数据。
  • 在服务器上对数据进行处理,就处理的结果生成网页,以方便客户端直接下载。
  • 在客户机上对数据的处理被进一步简化,将浏览器作为客户端的应用程序,以实现对数据的显示。不再需要为客户端单独编写和安装其他类型的应用程序。这样,在客户端只需要安装一套内置浏览器的操作系统,直接安装一套浏览器,就可以实现服务器上数据的访问。而浏览器是计算机的标准设备

总结一下,本质上:浏览器是一个socket客户端,服务器是一个socket服务端

二:编写web应用

基于socket写一个web应用

  • 手撸web框架
# 手撸web框架.py

# 你可以将web框架理解成服务端
import socket


server=socket.socket()
server.bind(("127.0.0.1",8080))
server.listen(5)

while True:
	conn,addr =server.accept()
	data = conn.recv(1024)
	print(data)            #二进制
	conn.send(b"HTTP/1.1 200 OK

")
	data = data.decode("urf-8")    #字符串
	# 获取字符串中特定的内容     正则    如果字符串有规律也可以考虑用切割
	conn.send(b"HTTP/1.1 200 OK

")
	current_path = data.split(" ").[1]
	# print(current_path)
	if current_path =="/index":
		# conn.send(b"index heiheihei")    #发送字符串
		with open(r"template/01 myhrml.html","rb") as f:      #发送文件
		conn.send(f.read())
	elif current_path =="/login":
		conn.send(b"login")
	else:
		# 你直接忽略favicon.ico
		conn.send(b"hello web")
	conn.close()
# 01 myhtml.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<h1>你好啊 宝贝</h1>
</body>
</html>
  • 不足之处
    • 代码重复(服务端代码所有人都要重复写)
    • 手动处理http格式的数据 并且只能拿到url后缀 其他数据获取繁琐(数据格式一样处理的代码其实也大致一样 重复写)
    • 并发的问题

借助于wsgiref模块

# 02 基于wsgiref模块.py

from wsgiref.simple_server import make_server
from urls import urls
from views import * 


def run(env,response):
	"""
	env:请求相关的所有的所有数据
	response:响应相关的所有数据
	return:返回浏览器的数据·
	"""
	# print(env)    #大字典,wsgiref模块帮你处理好http格式的数据   封装成了字典让你更加方便的操作
	# 从env中取
	response("200 ok",[])     #响应首行   响应头
	current_path = env.get("PATH_INFO")
	# if current_path =="/index":
		#return [b"index"]
	# elif current_path =="/login":
		# return [b"login"]
	# return [b"404 error"]
	# 定义一个变量   存储匹配到的函数名
	func = None
	for url in urls:   # url  (),()
		if current_path ==url[0]:
			# 将url对应的函数名赋值给func
			func = url[1]
			break    #匹配到一个之后   应该立即结束for 循环
		# 判断func是否有值
		if func:
			res = func(env)
		else:
			res = error(env)
		return [res.encode("utf-8")]

if __main__ =="__main__":
	server=make_server("127.0.0.1",8080,run)
	‘‘‘
	会实时监听127.0.0.1:8080的地址   只要有客户端来了   都会交给run函数处理(加括号触发run函数的运行)
	flask 启动源码
		make_server("127.0.0.1",8080,obj)
		__call__
	‘‘‘
	server.serve_forever()    #启动服务器
from view import * 
# url 与视图函数的对应关系

urls=[
("/index",index),
("/login",login),
("/xxx",xxx)
]
# views.py 文件

def index(env):
	return "index"
	
def login(env):
	return "login"

def xxx(env):
	with open(r"templates/02 myxxx.html","r",encoding="utf-8") as f:
		return f.read()
	
def error(env):
	return "404 error"
  • 文件拆分说明
urls.py              路由与视图函数对应关系
views.py             视图函数(后端业务逻辑)
templates文件夹       专门存放html文件

按照功能的不同拆分之后   后续添加功能只需要在urls.py书写对应关系   然后去views.py书写业务逻辑即可

动静态网页

静态网页
	页面上的数据是直接写死的    万年不变
动态网页
	数据是实时获取的
	eg:
		1.后端获取当前时间   展示到html页面上
		2.数据从数据库中获取的   展示到html页面上
  • 获取时间
#urls.py 文件

from view import * 
# url 与视图函数的对应关系

urls=[
("/index",index),
("/login",login),
("/xxx",xxx)
("/get_time",get_time)
]
view.py文件
 
import datetime
def get_time(env):
	current_time=datatime.datatime.new().strtime("%Y-%m-%d %X")
	# 如何将后端获取的数据“传递”给html文件?
	with open(r"templates/03 mytime.html","r",encoding="utf-8") as f:
		data = f.read()
		# data就算一堆字符串
	data = data.replace("ooxx",current_time)    #在后端将html页面处理好之后返回给前端
    return data
temlates文件夹下  03 mytime.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<h1>我真的是一个html文件</h1>
ooxx
</body>
</html>
  • 将一个字典传递给html文件 并且可以在文件上方便快捷的操作字典数据
    • 借助于jinja2模块
from jinja2 import Template

def get_dict(env):
	user_dict = {"username":"jason","age":18,"hobby":"read"}
	with open(r"template/04 get_dict.html","r",encoding="utf-8") as f:
		data = f.read()
	tmp = Template(data)
	res = tmp.render(user=user_dic)
	# get_dict.html 传递了一个值   页面上通过变量名user就能够拿到user_dict
	return res
"""模版语法是在后端起作用的"""

# 模版语法(非常贴近python语法)
{{ user }}
{{ user.get(‘username‘)}}
{{ user.age }}
{{ user[‘hobby‘] }}

{% for user_dict in user_list %}
                        <tr>
                            <td>{{ user_dict.id}}</td>
                            <td>{{ user_dict.username}}</td>
                            <td>{{ user_dict.password}}</td>
                            <td>{{ user_dict.hobby}}</td>
                        </tr>
{% endfor%}
  • 后端获取数据库中数据展示到前端页面
#urls.py 文件

from view import * 
# url 与视图函数的对应关系

urls=[
("/index",index),
("/login",login),
("/xxx",xxx),
("/get_time",get_time),
("/get_dict",get_dict)
]
views.py文件
 
import pymysql
def get_user(env):
	# 去数据库中获取数据   传递给html页面   借助于模版语法   发送给浏览器
	conn = pymysql.connect(
		host ="127.0.0.1",
		port = 3306,
		user = "root",
		password ="123",
		db="day059",
		charset = "utf-8",
		autocommit = True
	)
	cursor = conn.cursor(cursor = pymysql.cursors.DictCursor)
	sql = "select * from t1"
	affect_rows = cursor.execute(sql)
	data_list = cursor.fetchall()
	#将获取的数据传递给html文件
	with open(r"templates/111.html","r",encoding="utf-8") as f:
		data = f.read()
	tmp = Template(data)
	res = tmp.render(user_list=data_list)
	return res
templates文件下 111.html文件、

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1 class = "text-center">用户数据</h1>
    <table class="table table-hover table-striped">
       <thead>
        <tr>
            <th>ID</th>
            <th>username</th>
            <th>password</th>
            <th>hobby</th>
        </tr>
       </thead>
        <tbody>
        {% for user_dict in user_list %}
            <tr>
                <td>{{ use_dict.id }}</td>
                <td>{{ use_dict.username }}</td>
                <td>{{ use_dict.password }}</td>
                <td>{{ use_dict.hobby }}</td>
            </tr>
        {% endfor %}
        </tbody>



    </table>
</body>
</html>

自定义简易版本web框架请求流程图

wsgire 模块
	1.请求来的时候解析http格式的数据    封装成大字典
	2.响应走的时候给数据打包成符合http格式   再返回给浏览器

以上是关于web应用的主要内容,如果未能解决你的问题,请参考以下文章

PHP必用代码片段

JAVA WEB代码片段

web代码片段

如何将代码片段存储在 mongodb 中?

代码片段 - Golang 实现简单的 Web 服务器

高效Web开发的10个jQuery代码片段