一、浏览器请求HTML页面的过程

  了解了HTTP协议和HTML文档,其实就明白了一个Web应用的本质就是:

  1. 浏览器发送一个HTTP请求;

  2. 服务器收到请求,生成一个HTML文档;

  3. 服务器把HTML文档作为HTTP响应的Body发送给浏览器;

  4. 浏览器收到HTTP响应,从HTTP Body取出HTML文档并显示。

二、浏览器请求动态页面的过程

三、WSGI

1、WSGI介绍

PythonWeb服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是Python应用程序或框架和Web服务器之间的一种接口,

WSGI接口定义非常简单,它只要求Web开发者实现一个函数,就可以响应HTTP请求。

# WSGI 规范的函数
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return '<h1>Hello, Se7eN_HOU!</h1>'

上面的application()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数:

    • environ:一个包含所有HTTP请求信息的dict对象;

    • start_response:一个发送HTTP响应的函数。

application()函数中,调用:

start_response('200 OK', [('Content-Type', 'text/html')])

2、运行WSGI服务

1、 Python内置了一个WSGI服务器,这个模块叫wsgiref,首先我们先实现一个hello.py文件,实现Web应用程序的WSGI处理函数

def application(environ, start_response):
start_response("200 OK",[("Content-Type","text/html")])
return "<h1>Hello,Se7eN_HOU!</h1>"

2、然后,再编写一个server.py,负责启动WSGI服务器,加载application()函数: 

#coding:utf-8

# 导入wsgiref模块
from wsgiref.simple_server import make_server
from hello import application # 创建一个服务器,IP地址为空,端口号为7788,处理的函数是application
httpServer = make_server("", 7788, application)
# 开始监听HTTP请求
httpServer.serve_forever()

3、确保以上两个文件在同一个目录下,然后使用命令行输入python server.py来启动WSGI服务器:

houleideMacPro:WSGI Se7eN_HOU$ python server.py
127.0.0.1 - - [19/Jun/2019 15:52:37] "GET / HTTP/1.1" 200 24
127.0.0.1 - - [19/Jun/2019 15:52:37] "GET /favicon.ico HTTP/1.1" 200 24   

  4、 按Ctrl+C终止服务器。如果你觉得这个Web应用太简单了,可以稍微改造一下,从environ里读取PATH_INFO,这样可以显示更加动态的内容:

def application(environ, start_response):
start_response("200 OK",[("Content-Type","text/html")])
return "<h1>Hello,%s</h1>"%(environ["PATH_INFO"][1:] or "Se7eN_HOU")

  5、你可以在地址栏输入用户名作为URL的一部分,将返回Hello, xxx

四、动态web服务器案例

1、Daynamic.py

#coding=utf-8
import socket
import sys
from multiprocessing import Process
import re class WSGIServer(object): addressFamily = socket.AF_INET
socketType = socket.SOCK_STREAM
requestQueueSize = 5 def __init__(self, serverAddress):
#创建一个tcp套接字
self.listenSocket = socket.socket(self.addressFamily,self.socketType)
#允许重复使用上次的套接字绑定的port
self.listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#绑定
self.listenSocket.bind(serverAddress)
#变为被动,并制定队列的长度
self.listenSocket.listen(self.requestQueueSize) self.servrName = "localhost"
self.serverPort = serverAddress[1] def serveForever(self):
'循环运行web服务器,等待客户端的链接并为客户端服务'
while True:
#等待新客户端到来
self.clientSocket, client_address = self.listenSocket.accept() #方法2,多进程服务器,并发服务器于多个客户端
newClientProcess = Process(target = self.handleRequest)
newClientProcess.start() #因为创建的新进程中,会对这个套接字+1,所以需要在主进程中减去依次,即调用一次close
self.clientSocket.close() def setApp(self, application):
'设置此WSGI服务器调用的应用程序入口函数'
self.application = application def handleRequest(self):
'用一个新的进程,为一个客户端进行服务'
self.recvData = self.clientSocket.recv(2014)
requestHeaderLines = self.recvData.splitlines()
for line in requestHeaderLines:
print(line) httpRequestMethodLine = requestHeaderLines[0]
getFileName = re.match("[^/]+(/[^ ]*)", httpRequestMethodLine).group(1)
print("file name is ===>%s"%getFileName) #for test if getFileName[-3:] != ".py": if getFileName == '/':
getFileName = documentRoot + "/index.html"
else:
getFileName = documentRoot + getFileName print("file name is ===2>%s"%getFileName) #for test try:
f = open(getFileName)
except IOError:
responseHeaderLines = "HTTP/1.1 404 not found\r\n"
responseHeaderLines += "\r\n"
responseBody = "====sorry ,file not found===="
else:
responseHeaderLines = "HTTP/1.1 200 OK\r\n"
responseHeaderLines += "\r\n"
responseBody = f.read()
f.close()
finally:
response = responseHeaderLines + responseBody
self.clientSocket.send(response)
self.clientSocket.close()
else:
#处理接收到的请求头
self.parseRequest() #根据接收到的请求头构造环境变量字典
env = self.getEnviron() #调用应用的相应方法,完成动态数据的获取
bodyContent = self.application(env, self.startResponse) #组织数据发送给客户端
self.finishResponse(bodyContent) def parseRequest(self):
'提取出客户端发送的request'
requestLine = self.recvData.splitlines()[0]
requestLine = requestLine.rstrip('\r\n')
self.requestMethod, self.path, self.requestVersion = requestLine.split(" ") def getEnviron(self):
env = {}
env['wsgi.version'] = (1, 0)
env['wsgi.input'] = self.recvData
env['REQUEST_METHOD'] = self.requestMethod # GET
env['PATH_INFO'] = self.path # /index.html
return env def startResponse(self, status, response_headers, exc_info=None):
serverHeaders = [
('Date', 'Tue, 31 Mar 2016 10:11:12 GMT'),
('Server', 'WSGIServer 0.2'),
]
self.headers_set = [status, response_headers + serverHeaders] def finishResponse(self, bodyContent):
try:
status, response_headers = self.headers_set
#response的第一行
response = 'HTTP/1.1 {status}\r\n'.format(status=status)
#response的其他头信息
for header in response_headers:
response += '{0}: {1}\r\n'.format(*header)
#添加一个换行,用来和body进行分开
response += '\r\n'
#添加发送的数据
for data in bodyContent:
response += data self.clientSocket.send(response)
finally:
self.clientSocket.close() #设定服务器的端口
serverAddr = (HOST, PORT) = '', 8888
#设置服务器静态资源的路径
documentRoot = './html'
#设置服务器动态资源的路径
pythonRoot = './wsgiPy' def makeServer(serverAddr, application):
server = WSGIServer(serverAddr)
server.setApp(application)
return server def main(): if len(sys.argv) < 2:
sys.exit('请按照要求,指定模块名称:应用名称,例如 module:callable') #获取module:callable
appPath = sys.argv[1]
#根据冒号切割为module和callable
module, application = appPath.split(':')
print("module=%s"%module)
#添加路径套sys.path
sys.path.insert(0, pythonRoot)
#动态导入module变量中指定的模块
module = __import__(module)
#获取module变量中制定的模块的application变量指定的属性
application = getattr(module, application)
httpd = makeServer(serverAddr, application)
print('WSGIServer: Serving HTTP on port {port} ...\n'.format(port=PORT))
httpd.serveForever() if __name__ == '__main__':
main()

2、应用程序代码ctime.py

#coding:utf-8

import time

def app(environ, start_response):
status = "200 OK" response_headers = [
("Content-Type", "text/plain")
] start_response(status, response_headers)
return [str(environ)+'--->%s\n'%time.ctime()]

3、命令行执行代码 

4、浏览器运行结果

python网络-动态Web服务器案例(30)的更多相关文章

  1. python网络-静态Web服务器案例(29)

    一.静态Web服务器案例代码static_web_server.py # coding:utf-8 # 导入socket模块 import socket # 导入正则表达式模块 import re # ...

  2. python 启动简单web服务器

    有时我们在开发web静态页面时,需要一个web服务器来测试. 这时可以利用python提供的web服务器来实现. 1.在命令行下进入某个目录 2.在该目录下运行命令: python -m Simple ...

  3. python之Web服务器案例

    HTTP协议简介 1. 使用谷歌/火狐浏览器分析 在Web应用中,服务器把网页传给浏览器,实际上就是把网页的HTML代码发送给浏览器,让浏览器显示出来.而浏览器和服务器之间的传输协议是HTTP,所以: ...

  4. Python基础Web服务器案例

    一.WSGI 1.PythonWeb服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI) 是Python应用程序或框架和Web服务器之间的一种接口, ...

  5. 利用 python 实现对web服务器的目录探测

    一.pythonPython是一种解释型.面向对象.动态数据类型的高级程序设计语言.python 是一门简单易学的语言,并且功能强大也很灵活,在渗透测试中的应用广泛,让我们一起打造属于自己的渗透测试工 ...

  6. 利用Python实现对Web服务器的目录探测

    今天是一篇提升技能的干货分享,操作性较强,适用于中级水平的小伙伴,文章阅读用时约3分钟. PART 1/Python Python是一种解释型.面向对象.动态数据类型的高级程序设计语言. Python ...

  7. 基于python实现简单web服务器

    做web开发的你,真的熟悉web服务器处理机制吗? 分析请求数据 下面是一段原始的请求数据: b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8000\r\nConnectio ...

  8. 用python快速搭建WEB服务器

    cmd下进入你要搞WEB项目的目录 输入↓方代码 python -m SimpleHTTPServer 端口号# 默认是8000 这样就启动了一个简单的WEB服务器

  9. <5>Python的uwsgi web服务器

    一.是什么? uWSGI是web服务器,用来部署线上web应用到生产环境.uWSGI实现了WSGI协议.uwsgi协议.http协议.WSGI(Web Server Gateway Interface ...

随机推荐

  1. Windows常用命令的使用

    3.Tracert Tracert命令用来显示数据包到达目标主机所经过的路径,并显示到达每个节点的时间.该诊断实用程序将包含不同生存时间 (TTL) 值的 Internet 控制消息协议 (ICMP) ...

  2. AWD攻防赛之各类漏洞FIX方案

    笔者<Qftm>原文发布<FreeBuf>:https://www.freebuf.com/articles/web/208778.html

  3. PHP设计模式 - 桥接模式

    将抽象部分与它的实现部分分离,使他们都可以独立的变抽象与它的实现分离,即抽象类和它的派生类用来实现自己的对象 桥接与适配器模式的关系(适配器模式上面已讲解): 桥接属于聚合关系,两者关联 但不继承 适 ...

  4. Java开发笔记(一百二十九)Swing的输入框

    Swing的输入框仍然分成两类:单行输入框和多行输入框,但与AWT的同类控件相比,它们在若干细节上有所调整.首先说单行输入框,AWT的单行输入框名叫TextField,平时输入什么字符它便显示什么字符 ...

  5. 用Python递归做个多层次的文件执行

    想用 递归实现多层次的 '.py'执行但是发现好像不能 import os def func(path): if os.path.isdir(path): for name in os.listdir ...

  6. Kubernetes1.11.1 使用Nvidia显卡配置方法

    一.安装 1.1.kubernetes硬件支持问题说明 Kubernetes目前主要在很小程度上支持CPU和内存的发现.Kubelet本身处理的设备非常少.Kubernetes对于硬件都使用都依赖于硬 ...

  7. [转]HTTP Error 500.21 - Internal Server Error Handler "ExtensionlessUrlHandler-Integrated-4.0" has a bad module "ManagedPipelineHandler" in its module list

    1.错误 HTTP Error 500.21 - Internal Server Error Handler "ExtensionlessUrlHandler-Integrated-4.0& ...

  8. Javap与JVM指令

    一.javap命令简述 javap是jdk自带的反解析工具.它的作用就是根据class字节码文件,反解析出当前类对应的code区(汇编指令).本地变量表.异常表和代码行偏移量映射表.常量池等等信息.当 ...

  9. centos安装docker以及docker-compose

    1.yum更新 # sudo yum update 2.如果安装docker旧版本,旧版本的卸载 # sudo yum remove docker docker-common docker-selin ...

  10. canvas教程(二) 绘制直线

    经过 canvas 教程(一) 简介 我们知道了 canvas 的一些基本情况 而本次是给大家带来直线的绘制 canvas 中,基本图形有两种,一种是直线,还有一种是曲线 但是无论是直线还是曲线,我们 ...