django
django初识
django的本质就是基于socket通信
一。127.0.0.1 本地回环地址 后面:8001是端口号 /ppt是根目录下的ppt子网页
二。/当前网站的客户端(根目录)
例如:
127.0.0.1/#默认80可以不写
web框架的功能;
1.使用socket收发信息
2.根据不同路径返回不同的内容
3. 返回动态的数据(字符串的替换 模板的渲染)
web框架的几个开源版本
low版web框架
1 import socket
2 server=socket.socket()
3
4 server.bind(('127.0.0.1',8001))
5 server.listen()
6
7 while 1:
8 conn,addr=server.accept()
9
10 from_brower_msg=conn.recv(1024)
11 path=from_brower_msg.decode('utf-8').split(' ')[1]#对收到消息编码转换成字符串,切割成列表【0】是方法【1】是对应的页面
12 #GET / HTTP/1.1
13 #/是本页面的主页面 /后面的home page什么的都是对应的子页面
14 print(path)
15 conn.send(b'http/1.1 200 ok
')
16 if path'/':#读取文件都用rb
17 with open("04test.html",'rb')as f:
18 data=f.read()
19 elif path'/style.css':#判断路径是否存在
20 with open('style.css','rb')as f:
21 data=f.read()
22 elif path == '/mi.png':#每遇到一个url都会请求一次
23 with open('mi.png', 'rb') as f:
24 data = f.read()
25 elif path=="./test.js":
26 with open("test.js","rb")as f:
27 data=f.read()
28 conn.send(data)
29 conn.close()
html页面
24期官网
1 import socket
2 from concurrent.futures import ThreadPoolExecutor
3
4 server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
5 server.bind(("127.0.0.1",8848))
6 server.listen()
7
8 #一定记得关闭连接 等待下一个连接请求
9 #处理页面请求的函数
10 def home(conn):
11 with open('04test.html','rb')as f:
12 data=f.read()
13 conn.send(data)
14 conn.close()#关闭连接等待下一个请求
15 #处理页面link( )标签href属性值是本地路径的时候的请求
16 def css(conn):
17 with open('style.css','rb')as f:
18 data=f.read()
19 conn.send(data)
20 conn.close()#关闭连接
21 #处理页面script()标签src属性值是本地路径的时候的请求
22 def js(conn):
23 with open("test.js","rb")as f:
24 data=f.read()
25 conn.send(data)
26 conn.close()
27
28 #处理页面img标签src属性值是本地路径的时候的请求
29
30 def pic(conn):
31 with open("mi.png","rb")as f:
32 data=f.read()
33 conn.send(data)
34 conn.close()#关闭
35 while 1:
36 conn,addr=server.accept()
37 from_brower_msg = conn.recv(1024)
38 # print(from_brower_msg)
39 path = from_brower_msg.decode('utf-8').split(' ')[1]
40 print(path)
41 conn.send(b'HTTP/1.1 200 ok
')
42 urlpatterns = [
43 ('/',home),
44 ('/style.css',css),
45 ('/test.js',js),
46 ('/mi.png',pic)
47 ]
48 #线程池
49 for url in urlpatterns:
50 if path ==url[0]:
51 # ret=url)[1](
52 t=ThreadPoolExecutor()#开启一个线程池
53 t.submit(url[1],conn)#
54 break
55 else:
56 conn.send(b'404')
57 ············································ #多线程
58 for url in urlpatterns:
59 if path == url[0]:
60 t = Thread(target=url[1],args=(conn,))
61 t.start()
62 break
63 else:
64 conn.send(b'404')
jinja2 第三方内置框架和wsgiref类似socketserver
jinja2 本质是字符串替换
把数据库中查询到的内容进行文本的替换,读取用r
字符串替换replace
用jinja2独有的渲染方法 flask 里面的东西 没有渲染 利用jinja2渲染
wsgiref和jinja
from wsgiref.simple_server import make_server
from jinja2 import Template
def index():
把数据库中查询到的内容进行文本的替换,读取用r
with open("index2.html", "r",encoding='utf-8') as f:
data = f.read()
template = Template(data) # 生成模板文件
ret = template.render({"name": "于谦", "hobby_list": ["烫头", "泡吧"]}) # 把数据填充到模板里面
return [bytes(ret, encoding="utf8"), ]
定义一个url和函数的对应关系
URL_LIST = [
("/index/", index),
]
environ返回的是一个字典
def run_server(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息
url = environ['PATH_INFO'] # 取到用户输入的url
func = None # 将要执行的函数
for i in URL_LIST:
if i[0] == url:
func = i[1] # 去之前定义好的url列表里找url应该执行的函数
break
if func: # 如果能找到要执行的函数
return func() # 返回函数的执行结果
else:
return [bytes("404没有该页面", encoding="utf8"), ]
if name == 'main':
httpd = make_server('', 8000, run_server)
print("Serving HTTP on port 8000...")
httpd.serve_forever()#发送给浏览器
html
姓名:{{name}}
#第一种写法爱好:
-
{% for hobby in hobby_list %}#第二种写法循环键值对
- {{hobby}} {% endfor %}
http 规定请求和响应的标准
get获取数据 post 提交数据
1.客户端链接web服务器
2.发送http请求
3.服务器接收请求并返回http响应
4.释放链接tcp连接
5.客户端浏览器解析html内容
http的分为两种
短链接和无连接 无状态
无连接发送完就断开链接,
无连接有两种模式
短链接
发送完数据等待几秒客户端的操作
无状态
不会保留状态
http
http协议
请求信息格式
GET / HTTP/1.1 请求行
Host: 127.0.0.1:8003 请求头
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
指定 浏览器格式
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
空行
请求数据 username=ziwen password=666
get请求 请求数据部分是没有数据的,get请求的数据在url上,在请求行里面,有大小限制,常见的get请求方式: 浏览器输入网址,a标签
post请求 请求数据在请求体(请求数据部分) ,数据没有大小限制, 常见方式:form表单提交数据
HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据.
以下是 HTTP 请求/响应的步骤:
- 客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如,http://www.luffycity.com。 - 发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。 - 服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。 - 释放连接TCP连接
若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求; - 客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
在浏览器地址栏键入URL,按下回车之后会经历以下流程:
1.浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
2.解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;
3.浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;(根据不同路径返回不同数据)
4.服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
5.释放 TCP连接;(conn.close())因为tcp是长连接 http协议的特点
6.浏览器将该 html 文本并显示内容;
请求方法
八种动作
常用get post
#GET
//向指定的资源发出“显示”请求。使用GET方法应该只用在读取数据,而不应当被用于产生“副作用”的操作中,例如在Web Application中。其中一个原因是GET可能会被网络蜘蛛等随意访问。
#HEAD//
//与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中“关于该资源的信息”(元信息或称元数据)。
#POST
//向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。(把信息放入了请求数据)
PUT
//向指定资源位置上传其最新内容。
DELETE
//请求服务器删除Request-URI所标识的资源。
TRACE
//回显服务器收到的请求,主要用于测试或诊断。
OPTIONS
//这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用'*'来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。
#CONNECT
//HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由加密的HTTP代理服务器)。
http状态码
1xx消息——请求已被服务器接收,继续处理
2xx成功——请求已成功被服务器接收、理解、并接受
3xx重定向——需要后续操作才能完成这一请求
4xx请求错误——请求含有词法错误或者无法被执行
5xx服务器错误——服务器在处理某个正确请求时发生错误
重定向
例如一个http:jd.com/auth
1.输入 username和passwerd 提交数据
2.判断用户是否合法
3.如果是重定向 3xx
4.浏览器拿到网址,get请求获取对应的html
首页 http:www.jd.com
mvc和mtv框架
mvc
M --- models 数据库相关
v --- views 视图相关(逻辑)
C -- controller url控制器(url分发器,路由分发)
django-mtv
M -- models 数据库相关
T -- templates HTML相关 html就是模板
V -- views 视图相关(逻辑)s
+ controller url控制器(url分发器,路由分发)
url
https默认 443端口
http默认 80端口
查询参数
?k1=v1&k2=v2
超文本传输协议(HTTP)的统一资源定位符将从因特网获取信息的五个基本元素包括在一个简单的地址中:
传送协议。
层级URL标记符号(为[////],固定不变)
访问资源需要的凭证信息(可省略)
1.服务器。
#//(通常为域名,有时为IP地址(dns解析))
2.端口号。
//(以数字方式表示,若为HTTP的默认值“:80”可省略)
路径。
//(以“/”字符区别路径中的每一个目录名称)
查询。
//(GET模式的窗体参数,以“?”字符为起点,每个参数以“&”隔开,再以“=”分开参数名称与数据,通常以UTF8的URL编码,避开字符冲突的问题)
片段。
//以“#”字符为起点
····································
以http://www.luffycity.com:80/news/index.html?id=250&page=1 为例, 其中:
1. http,是协议;
2. www.luffycity.com,是服务器;
3. 80,是服务器上的网络端口号;
4. /news/index.html,是路径;
5. ?id=250&page=1,是查询。
大多数网页浏览器不要求用户输入网页中“http://”的部分,因为绝大多数网页内容是超文本传输协议文件。同样,“80”是超文本传输协议文件的常用端口号,因此一般也不必写明。一般来说用户只要键入统一资源定位符的一部分(www.luffycity.com:80/news/index.html?id=250&page=1)就可以了。
响应格式
url是127.0.0.1 /路径
响应可以不写头部字段 在回复信息的时候可以定制响应头
wsgi 是一种规范定义python的接口规范 可以搭配不同的应用程序
本地测试用wsgiref
请求(网址访问,提交数据等等) request
响应(回复页面,回复数据等等) response
下载安装django
pip3 install django==1.11.23
django创建项目
命令行
下载安装django
pip3 install django==1.11.23
pip3 install django==1.11.23 http://mirrors.aliyun.com/pypi/simple/
python36 manage.py runserver#开启django项目
python36 manage.py runserver 80 把端口号改成默认80
python36 manage.py runserver 0.0.0.0:80 其他人就可以访问了
djnago的py文件的分类
1.manage.py ----- Django项目里面的工具,通过它可以调用django shell和数据库,启动关闭项目与项目交互等,不管你将框架分了几个文件,必然有一个启动文件,其实他们本身就是一个文件。
2.settings.py ---- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
3.urls.py ----- 负责把URL模式映射到应用程序w。
4.wsgi.py ---- runserver命令就使用wsgiref模块做简单的web server,后面会看到renserver命令,所有与socket相关的内容都在这个文件里面了,目前不需要关注它。
子项目的文件分类
views是写视图函数 视图类 代码逻辑
models是数据库的源 写与数据库相关的的
templatses 是模板 放置html xml等网络文件
wsgi用于书写socket
django基本操作
request对象 封装了所有请求
request.method是当前请求方法
.post 获取post请求的数据
.get 获取get请求的数据
request.GET.get('pwd') 获取get 字典的值
request.POST.get('pwd')获取post 字典的值
post。get(“键”)取得的值是一个字符串
·······································
注意'django.middleware.csrf.CsrfViewMiddleware',#安全机制
返回一个字典 获取值要把一个安全机制注释才能过
需要引用模块
关键字
from django.shortcuts import render,HttpResponse#引用一个快捷键
render (request,'home.html')
#模板渲染 模板就是html页面 渲染就是字符串替换
HttpResponse("")
#传入一个字符串 向浏览器返回一个页面
视图函数
视图函数
def articles(request,year,month): # 位置参数(形参) 2019 9
print(year,type(year)) #2019 <class 'str'>
#匹配出来的所有数据都是字符串
print(month)
return HttpResponse(year+'年'+ month +'月' +'所有文章')
# 无名分组参数
url(r'^articles/(d+)/(d+)/', views.articles), #articles/2019/9/
# 有名分组参数
url(r'^articles/(?P<xx>d+)/(?P<oo>d+)/', views.articles), #articles/2019/9/
#xx=2019 oo=9 关键字传参
def articles(request,oo,xx): # 关键字传参 2019 9
print(xx,type(xx)) #2019 <class 'str'> #匹配出来的所有数据都是字符串
print(oo)
return HttpResponse(xx+'年'+ oo +'月' +'所有文章')
有名函数
# 有名分组参数
url(r'^articles/(?P<xx>d+)/(?P<oo>d+)/', views.articles), #articles/2019/9/
#xx=2019 oo=9 关键字传参
def articles(request,oo,xx): # 关键字传参 2019 9
print(xx,type(xx)) #2019 <class 'str'> #匹配出来的所有数据都是字符串
print(oo)
return HttpResponse(xx+'年'+ oo +'月' +'所有文章')
无名分组参数
# 无名分组参数
url(r'^articles/(d+)/(d+)/', views.articles), #articles/2019/9/
正则分组/(d+)/(d+)/会把匹配的 一一对应单独存储一个变量
(d+)正则贪婪 满足一个或多个整数
具体示例
例如/articles/2019/9会把路径进行正则匹配
#(要一一对应)
url(r"^articles/(d+)/(d+)/",views.articles),
#匹配的时候,返回对应的匹配的内容,
#articles是返回路径 两个参数进行
视图函数(request请求)补充
request是wsgirequest实例化的对象
1.print(request)打印出来的是--str--的返回值
requesrt这个对象含有————str————
#返回的都是字符串
2.print(request.path) #/home/ 纯路径
3.print(request.path_info) #/home/ 纯路径
4.print(request.get_full_path()) #/home/?a=1&b=2 全路径(不包含ip地址和端口)
5.print(request.body) 能够拿到请求数据部分的数据(post,get没有),get数据的内容在url里
6.print(request.META)
是一个Python字典,包含了所有本次HTTP请求的Header信息
查看需要在线json转换
user-agent返回
7.print(request.GET)返回get请求的数据类似字典的值
8.print(request.POST)返回get请求的数据类似字典的值
访问其他路径服务端会返回状态信息(状态码)
response响应的三个方法
三个方法都需要模块的引用
底部都有一个httpResponse 把字符串传入页面
form django.shortcuts import render,HttpResponse,redirect
1.HTTPResponse('字符串')#传入一个字符串 向浏览器返回一个页面
render 和redirect都是通过httpresponse传递给浏览器
2.render(request,'xx.html')返回浏览器一个xx.html
#模板渲染 模板就是html页面 渲染就是字符串替换
'''
示例
'''
#home.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>24期官网</h1>
<h2>{{ namxx }}</h2>
</body>
</html>
#views视图.py (render有第三个参数是html传参使用)
def home(request):
name = 'chao'
return render(request, 'home.html', {'namxx':name,}) #模板渲染(先把字符串替换了),这是在回复给浏览器之前做的事情
·······································
3.redirect 重定向
#用法 redirect(路径) 示例:redirect('/index/')
会返回浏览器3xx一个重定向 返回一个redirect('/index/')路径
redirect示例
浏览器访问/index/#例如127.0.0.1/index/
urls.py
from django.conf.urls import url
from django.contrib import admin
from Django_test import views#引用 视图函数模块
urlpatterns = [
url(r'^index/', views.index),
]
def home(request):
print('xxxxx')
return redirect('/index/') #重定向路径
FBV和CBV 视图(视图函数和视图类)
FBV是视图函数
def 函数名(request):
函数体#进行判断
return 要一个返回值返回给浏览器
CBV是视图类
urls写法
url(r'^login',views.LoginView.as_view())
1.加载到这一句的时候LoginView这个类直接调用执行类方法,LoginView没有as_view方法 去父类View去寻找这个方法
2.执行完之后返回一个view方法名
3.相当于视图函数#执行url(r'^login',views.view)
4.等待源码调用view方法(函数)
views视图类的写法
from django.views import View#引用View方法
class LoginView(View):#创建一个类 继承父类view
def get(self,request):##处理get请求直接定义get方法,不需要自己判断请求方法了,源码中用dispatch方法中使用了反射来处理的
print('小小小小')
return render(request,'login.html')
def post(self,request)
view源码简化分析
执行步骤:
1.加载类名去调用执行as_view方法#views.loginview.as_view()#as_view
2.as_view返回一个view方法名
3.urls执行view方法
4.执行到view方法self = cls(**initkwargs)#实例化一个对象cls对应的就是 LoginView视图类
5. 继续往下执行return self.dispatch(request, *args, **kwargs)#这时self是LoginView视图类的实例化对象 去LoginView类中去寻找dispatch方法
6.LoginView视图类没有找到去对应的父类View去寻找
dispatch方法
7.找到http_method_names对应属性里面有各类方法
8.请求的方法名在这个属性中继续往下执行反射
9.利用反射去寻找对应的方法,如果找不到对应方法执行第三个参数报错
#注意
getattr 第二个参数找不到就执行第三个参数 执行第三个方法直接报错返回 日志打印405
父类view
class View(object):
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
@classonlymethod
def as_view(cls, **initkwargs):
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError("You tried to pass in the %s method name as a "
"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
if not hasattr(cls, key):
raise TypeError("%s() received an invalid keyword %r. as_view "
"only accepts arguments that are already "
"attributes of the class." % (cls.__name__, key))
2.#as_view里面有一个view方法
def view(request, *args, **kwargs):
self = cls(**initkwargs)
3.#实例化cls方法(就是LoginView视图类) 拿到自己类的对象
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)
4.#执行到这发现 类调用一个方法 去试图类(LoginView)寻找dispatch方法,没有这个方法就去继承的父类去寻找 执行
view.view_class = cls
view.view_initkwargs = initkwargs
update_wrapper(view, cls, updated=())
update_wrapper(view, cls.dispatch, assigned=())
return view 1.#返回一个view方法
"""
dispatch方法
"""
5.找到dispatch方法执行
def dispatch(self, request, *args, **kwargs):
#request.method.lower()取得请求对应的方法 方法名都是大写的所以需要小写对应
#http_method_names去LoginView类去找,找不到去在源码中寻找(也就是继承的父类)
if request.method.lower() in self.http_method_names:
#请求的方法名在这个属性中继续往下执行反射
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
#利用反射去寻找对应的方法
#getattr 第二个参数找不到就执行第三个参数 执行第三个方法直接报错返回 日志打印405
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
'''http_method_not_allowed方法'''
```python
def http_method_not_allowed(self, request, *args, **kwargs):
logger.warning(
'Method Not Allowed (%s): %s', request.method, request.path,
extra={'status_code': 405, 'request': request}
)
return http.HttpResponseNotAllowed(self._allowed_methods())
类名里面有一个视图方法
```python
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
getattr 第二个参数找不到就执行第三个参数
想法 在进行分发操作之前想要执行一些命令
自己重构父类的时候必须执行父类的分发操作
如果没有这个方法他会报错(重构父类dispatch方法)
class LoginView(View):
def dispatch(self,request,*args,**kwargs):
print("xxx请求来了")
ret=super(LoginView,self).dispatch(request,*args,**)
重构父类(view)的dispatch方法
#def dispatch(self, request, *args, **kwargs):
# if request.method.lower() in self.http_method_names:
#handler = getattr(self,request.method.lower(),
#self.http_method_not_allowed)
# else:
#handler = self.http_method_not_allowed
#return handler(request, *args, **kwargs)
#执行对应方法 获得返回值
print("执行结束")
return ret
#相当于执行return handler(request, *args, **kwargs)
def get(self,request):
print('xxxx')
return render(request,"login.html")
def post(self,request):
print(request.POST)
return HttpResponse('登录成功')
图解
![1569416028460](C:Users安小文AppDataRoamingTypora ypora-user-images1569416028460.png)
装饰器
有三种方式
在类上面必须指定请求方法
from django.utils.decorators import method_decorator
#必须引用django封装的装饰器
def wrapper(func):
def inner(*args, **kwargs):
print(11111)
ret = func(*args, **kwargs)
print(22222)
return ret
return inner
@method_decorator(wrapper,name='get')#第一种放松
class LoginView(View):
def get(self,request):
print('xxxx')
return render(request,"login.html")
@method_decorator(wrapper) #方式2
def dispatch(self, request, *args, **kwargs):
print('xx请求来啦!!!!')
ret = super().dispatch(request, *args, **kwargs)
print('请求处理的逻辑已经结束啦!!!')
return ret
@method_decorator(wrapper)#方式3
def post(self,request):
print(request.POST)
return HttpResponse('登录成功')
模板渲染
开源的djnago初识
low版登陆跳转页面
思路
1.开启django 配置好路径
2.在浏览器访问路径例如:#127.0.0.1(回环地址)/后面写路径
3.路径的相应的请求 去urls这个文件去寻找相应匹配的路径 ,调用相应视图函数(views是视图函数)
4.根据对应匹配的函数 返回浏览器相应的页面
render(requset,返回页面)
第一个为 固定requset
例如#return render(request,"home.html")
第三方模块
jinja2 本质是字符串替换
使用数据库进行 文本的替换
用jinja2独有的渲染方法 flask 里面的东西 没有渲染 利用jinja2渲染
wsgiref模块web框架
1 from wsgiref.simple_server import make_server
2 # wsgiref本身就是个web框架,提供了一些固定的功能(请求和响应信息的封装,不需要我们自己写原生的socket了也不需要咱们自己来完成请求信息的提取了,提取起来很方便)
3 #函数名字随便起
4 def application(environ, start_response):
5 '''
6 :param environ: 是全部加工好的请求信息,加工成了一个字典,通过字典取值的方式就能拿到很多你想要拿到的信息
7 :param start_response: 帮你封装响应信息的(响应行和响应头),注意下面的参数
8 :return:
9 '''
10 start_response('200 OK', [('Content-Type', 'text/html'),('k1','v1')])
11 print(environ)
12 print(environ['PATH_INFO']) #输入地址127.0.0.1:8000,这个打印的是'/',
13 #输入的是127.0.0.1:8000/index,打印结果是'/index'
14 return [b'<h1>Hello, web!</h1>']
15
16 #和咱们学的socketserver那个模块很像啊
17 httpd = make_server('127.0.0.1', 8080, application)
18
19 print('Serving HTTP on port 8080...')
20 # 开始监听HTTP请求:
21 httpd.serve_forever()