web框架原理
Posted 显示名称已经被使用
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了web框架原理相关的知识,希望对你有一定的参考价值。
Web框架本质:
Web应用本质上就是socket服务器.而用户的浏览器就是一个scoket客户端
import socket sk = socket.socket() sk.bind(("127.0.0.1", 80)) sk.listen() while True: conn, addr = sk.accept() data = conn.recv(8096) conn.send(b\'ok\') conn.close()
可以说web服务本质上就是这是几行代码基础上扩展出来的,这段代码就是他们的祖宗
用户再浏览器中输入网址,浏览器会像服务器发送数据,那浏览器会发送什么数据呢?
规定HTTP协议,以后浏览器发送请求信息也好,服务器响应,都按照这个规则来.
HTTP协议主要规定了客户端和服务器之间的通信格式,那HTTP协议是怎么规定消息格式的呢?
import socket sk = socket.socket() sk.bind(("127.0.0.1", 8000)) sk.listen() while True: conn, addr = sk.recv(8096) data = conn.recv(8096) print(data) conn.send(b\'ok\') conn.close()
输出:
b\'GET / HTTP/1.1\\r\\nHost: 127.0.0.1:8080\\r\\nConnection: keep-alive\\r\\nCache-Control: max-age=0\\r\\nUpgrade-Insecure-Requests: 1\\r\\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/66.0.3355.4 Safari/537.36\\r\\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\\r\\nAccept-Encoding: gzip, deflate, br\\r\\nAccept-Language: zh-CN,zh;q=0.9\\r\\nCookie: csrftoken=CtHePYARJOKNx5oNVwxIteOJXpNyJ29L4bW4506YoVqFaIFFaHm0EWDZqKmw6Jm8\\r\\n\\r\\n\'
将\\r\\n替换成换行;
GET / HTTP/1.1 Host: 127.0.0.1:8080 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3355.4 Safari/537.36 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 Cookie: csrftoken=CtHePYARJOKNx5oNVwxIteOJXpNyJ29L4bW4506YoVqFaIFFaHm0EWDZqKmw6Jm8
HTTP协议对手法消息的格式要求
每个HTTP请求和响应都应遵循相同的格式, 一个HTTP包含Header和Boby两部分,其中送Boby都可选的.
HTTP响应的Header中有一个Content-Type表名响应的内容格式,他的值如text/html;charset=utf-8
text/html表示网页,charset-utf-8表示编码为utf-8
HTTP GET请求的格式;
HTTP 响应的格式;
自定义web框架
import socket sk = socket.socket() sk.bind(("127.0.0.1", 8000)) sk.listen() while True: conn, addr = sk.accept() data = conn.recv(8096) # 给回复的消息加上响应状态行 conn.send(b\'HTTP/1.1 200 ok\\r\\n\\r\\n\') conn.send(b\'ok\') conn.close()
通过以上的代码让网页能够动态的显示
import socket sk = socket.socket() sk.bind(("127.0.0.1", 8080)) sk.listen() # 返回不同的内容部分封装成不同的函数 def timer(): import time date = time.strftime("%Y-%m-%d %H:%M:%S") with open("time.html", \'r\', encoding=\'utf-8\') as f: ret = f.read() ret = ret.replace(\'time\', date) return ret.encode("utf-8") # 定义一个url和实际要执行的函数的对应关系 list1 = [ ("/time/", timer) ] while True: # 等待连接 conn, addr = sk.accept() data = conn.recv(8000) url = data.decode("utf-8").split()[1] # 按照空格分割获取路径 conn.send(b\'HTTP/1.1 200 ok\\r\\n\\r\\n\') # 发送遵循的HTTP协议和回复的状态代码 func = None for i in list1: if i[0] == url: # 浏览器发来的地址取出来的地址 /admin/ func = i[1] break if func: response = func() else: response = b\'404 not found\' # 发送相应函数的返回的值 conn.send(response) conn.close()
服务器和应用程序
对于python web来说: 会分为两部分: 服务器和应用程序.
服务器看程序负责对socket服务端进行封装,并在请求到来的时候,对请求的各种数据进行整理
应用该程序则负责的逻辑处理,为了方便应用程序的开发, 就会出现了众多的lweb框架,例如django,flask,web.py等, 不同的框架有不同的开发方式,但是无论如何,可发出的应用程序都要和服务器程序配合,才能为用户提供服务
这样,服务器程序就需要不同的框架提供不同的支持, 这样混乱的局面无论对于服务器还是框架, 都是不好的,对于服务区来说,需要支持各种不同框架,对框架来说,只有支持他的服务器猜能被开开发出应用使用.
这时候,标准化就尤为重要, 我们可以设立一个及标准,只要付挤程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用,一旦标准确定,双方各自实现.这样,服务器可以支持个多支持标准的框架, 框架一个可以使用更多支持标准的服务器
WSGI(web Server Gateway Interfase)就是一种规范,他定义了使用Python编写的web应用程序与web服务器程序之间额接口格式,实现web应用程序与web服务器程序间的解耦
常用的WSGI服务器又uwsgi, Gunicorn.二Python标准库提供的独立WSGI服务叫wsgiref,Diando开发环境用的就是这个模块来做的服务器
wsgiref
我们利用wsgiref模块来替换我们自己写的web框架的socket.server部分
\'\'\' 根据URL中不同的路径返回不同的内容--函数进阶 返回HTML页面 让页面动态起来 wsgiref模块版 \'\'\' from wsgiref.simple_server import make_server # 将返回的不同的内容部分封装成函数 def index(url): # 读取index.html页面的内容 with open(\'index.html\', \'r\', encoding=\'utf-8\') as f: s = f.read() # 返回字节数据 return bytes(s, encoding=\'utf-8\') def home(url): with open(\'home.html\', \'r\', encoding=\'utf-8\') as f: s = f.read() return bytes(s, encoding=\'utf-8\') def timer(url): import time with open(\'time.html\', \'r\', encoding=\'utf-8\') as f: s = f.read() s = s.replace("time", time.strftime("%Y-%m-%d %H:%M:%S")) return bytes(s, encoding=\'utf-8\') # 定义一个url和实际要执行的函数的对应关系 list1 = [ (\'/index/\', index), (\'home/\', home), (\'/time/\', timer) ] def run_server(environ, start_response): start_response(\'200 ok\', [(\'Content-Type\', \'text/html; charset=utf-8\'), ]) # 设置HTTP响应状态和头信息 url = environ[\'PATH_INFO\'] # 获取用户输入的url func = None for i in list1: if i[0] == url: func = i[1] if func: response = func(url) else: response = b\'404 not found\' return [response, ] if __name__ == \'__main__\': httpd = make_server(\'127.0.0.1\', 8090, run_server) print("8090......") httpd.serve_forever()
Django
安装Django===(安装django1.11.15)
pip3 install django==1.11.15
创建一个django项目:
django-admin startproject projectname
mysite/ ├── manage.py # 管理文件 └── mysite # 项目目录 ├── __init__.py ├── settings.py # 配置 ├── urls.py # 路由 --> URL和函数的对应关系 └── wsgi.py # runserver命令就使用wsgiref模块做简单的web server
运行django项目
python manage.py runserver 127.0.0.1: 8000
模板文件配置
TEMPLATES = [ { \'BACKEND\': \'django.template.backends.django.DjangoTemplates\', \'DIRS\': [os.path.join(BASE_DIR, "template")], # template文件夹位置 \'APP_DIRS\': True, \'OPTIONS\': { \'context_processors\': [ \'django.template.context_processors.debug\', \'django.template.context_processors.request\', \'django.contrib.auth.context_processors.auth\', \'django.contrib.messages.context_processors.messages\', ], }, }, ]
静态文件配置:
STATIC_URL = \'/static/\' # HTML中使用的静态文件前缀 STATICFILES_DIRS = [ os.path.join(BARSE_DIR, \'static\'), # 静态文件存放位置 ]
刚开始学习是时可在配置文件中禁用csrf中间件,方便表单提交测试
MIDDLEWARE = [ \'django.middleware.security.SecurityMiddleware\', \'django.contrib.sessions.middleware.SessionMiddleware\', \'django.middleware.common.CommonMiddleware\', # \'django.middleware.csrf.CsrfViewMiddleware\', \'django.contrib.auth.middleware.AuthenticationMiddleware\', \'django.contrib.messages.middleware.MessageMiddleware\', \'django.middleware.clickjacking.XFrameOptionsMiddleware\', ]
Django基础必备的三件套:
from django.shortcuts import HttpResponse, render, redirect
HttpResponse
内部传入一个字符串参数,返回给浏览器.
例如:
def index(request): # 业务逻辑代码 return HttpResponse("OK")
render
除了request参数外还接受一个待渲染的模板文件和一个保存具体数据的字典参数.
将数据填充模板文件, 最后把结构返回给浏览器.(类似于我们上面用到的jinja2)
例如:
def index(request): # 业务逻辑代码 return render(request, "index.html", {"name": "alex", "hobby": ["烫头", "泡吧"]})
redirect
接受一个url参数,表示跳转到指定的url
例如:
def index(request): # 业务逻辑代码 return redirect("/home/")
重定向是怎么回事?
重定向(Redirect)就是通过各种方法将各种网络请求重新定个方向转到其他位置
1,网站调整
2,网页被移到一个新的地址
3,网页扩展名改变(如应用需要把.php改成.html或.shtml)
这种情况下,如果不做重定向,则用户收藏夹或搜索数据库中旧地址只能访问一个404错误信息,流量白白流失.
启动django报错
Django 启动时报错 UnicodeEncodeError ...
报这个错误通常是因为计算机名为中文,改成英文的计算机名重启下电脑就可以了。
以上是关于web框架原理的主要内容,如果未能解决你的问题,请参考以下文章
text 来自Codyhouse框架的Browserlist片段源代码