作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
Web 基础
-
HTTP 协议
我们平时都会通过百度查询内容,在这个过程中,用户浏览器被称为客户端,而百度网站被称为服务器。这个过程实质上就是客户端向服务器发起请求,服务器接收请求后,将处理后的信息(也成为响应)传给客户端。这个过程就是通过 HTTP 协议实现的。
HTTP(HyperText Transfer Protocol)超文本传输协议,是互联网上应用最为广泛的一种网络协议。HTTP 是利用 TCP 在两台计算机(通常是 Web 服务器和客户端)之间传输信息的协议。客户端使用 Web 浏览器发起 HTTP 请求给 Web 服务器,Web 服务器发送被请求的信息给客户端。 -
Web 服务器
当在浏览器输入 URL 后,浏览器会先请求 DNS 服务器,获得请求站点的 IP 地址(即根据 URL 地址 www.baidu 获取其对应的 IP 地址,如 104.193.88.123),然后发送一个 HTTP Request(请求)给拥有该 IP 的主机(百度的服务器在美国芝加哥),接着就会接收到服务器返回的 HTTP Response(响应),浏览器经过渲染后,以一种较好的效果呈现给用户。
我们重点来看一下 Web 服务器,Web 服务器的工作原理可以概括为以下 4 个步骤:
- 建立连接:客户端通过 TCP/IP 协议建立到服务器的 TCP 连接;
- 请求过程:客户端向服务器发送 HTTP 协议请求包,请求服务器里的资源文档;
- 应答过程:服务器向客户端发送 HTTP 协议答应包,如果请求的资源包含有动态语言的内容,那么服务器会调用动态语言的解释引擎负责处理 “动态内容”,并将处理后得到的数据返回给客户端。有客户端解释 HTML 文档,在客户端屏幕上渲染图形结果;
- 关闭连接:客户端与服务器断开连接;
HTTP 协议的常用请求方法:
方法 | 描述 |
---|---|
GET | 请求指定的页面信息,并返回实体主体 |
POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件),数据被包含在请求体中 |
HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
PUT | 从客户端向服务器传送的数据取代指定的文档的内容 |
DELETE | 请求服务器删除指定的页面 |
OPTIONS | 允许客户端查看服务器的性能 |
HTTP 状态码含义:
代码 | 含义 |
---|---|
1** | 信息,请求收到,继续处理 |
2** | 成功,行为被成功地接收、理解和采纳 |
3** | 重定向,为了完成请求,必须进一步执行的动作 |
4** | 客户端错误,请求包含语法错误或者请求无法实现 |
5** | 服务器错误,服务器不能实现一种明显无效的请求 |
具体每一项代表的含义,可以参考:HTTP状态码详解
- 前端基础
对于 Web 开发,通常分为前端(Front-End)和后端(Back-End)。“前端” 是与用户直接交互的部分,包括 Web 页面的结构、Web 的外观视觉表现以及 Web 层面的交互实现。“后端” 更多的是与数据库进行交互,处理相应的业务逻辑。需要考虑的是如何实现功能、数据的存取、平台的稳定性与性能等。后端的编程语言包括 Python、Java、PHP、ASP.NET 等,而前端编程语言包括 HTML、CSS 和 JavaScript。
HTML 是用来描述网页的一种语言。HTML 指的是超文本标记语言(Hyper Text Markup Language),它不是一种编程语言,而是一种标记语言。标记语言是一套标记标签,这种标记标签通常被称为 HTML 标签,它们是由尖括号包围的关键词,比如 。HTML 标签通常是成对出现的,第一个标签是开始标签,第二个标签是结束标签。Web 浏览器的作用是读取 HTML 文档,并以网页的形式显示它们。浏览器不会显示 HTML 标签,而是使用标签来解释页面的内容。
CSS 是 Cascading Style Sheets(层叠样式表)的缩写。CSS 是一种标记语言,用于为 HTML 文档中定义布局。例如,CSS 涉及字体、颜色、边距、高度、宽度、背景图像、高级定位等方面。运用 CSS 样式可以让页面变的美观,就像爱那个化妆前和化妆后的效果一样。
JavaScript 是一种可以嵌入在 HTML 代码中,由客户端浏览器运行的脚本语言。在网页中使用 JavaScript 代码,不仅可以实现网页特效,还可以响应用户请求,实现动态交互的功能。例如,在用户注册页面中,需要对用户输入信息的合法性进行验证,包括是否填写了 “邮箱” 和 “手机号”,填写的格式是否正确等。
作为 Python Web 初学者,只要掌握基本的前端知识即可。想了解更多关于前端的内容,可以参考以下两个网站:
- w3school
- 菜鸟教程
静态服务器
对于 Web 开发,我们需要让用户在浏览器中看到完整的 Web 页面(也就是 HTML),在 Web 中,纯粹的 HTML 格式的页面通常被称为 “静态页面”,早期的网站通常都是由静态页面组成的。例如马云早期的创业项目 “中国黄页” 网站就是由静态页面组成的静态网站。下面通过实例结合 Python 网络编程和 Web 编程,创建一个静态服务器。
- 创建 views 文件夹,在 views 文件夹下创建 index.html 页面作为首页,index.html 的代码如下:
<!DOCTYPE html>
<html lang="UTF-8">
<head>
<title>
我的博客
</title>>
</head>>
<body class="bs-docs-home">
<!--Docs master nav-->
<header class="navbar navbar-static-top bs-docs-nav" id="top">
<div class="container">
<div class="navbar-header">
<a href="/" class="navbar-brand">我的博客</a>>
</div>
<nav id="bs-navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li>
<a href="https://blog.csdn/qq_34139994/article/details/107725117">Python 进阶之路</a>
</li>
<li>
<a href="https://blog.csdn/qq_34139994/article/details/97393033">Qt 进阶之路</a>
</li>
<li>
<a href="https://blog.csdn/qq_34139994/article/details/104144719">我的网址收藏</a>
</li>
<li>
<a href="https://blog.csdn/qq_34139994/article/details/93847054">设计模式</a>
</li>
<li>
<a href="https://blog.csdn/qq_34139994/article/details/105390364">请善待90后</a>
</li>
<li>
<a href="/contact.html">联系博主</a>
</li>
</ul>
</nav>
</div>
</header>>
<!--Page content of coursel-->
<main class="bs-docs-masthead" id="content" tabindex="-1">
<div class="container">
<span class="bs-docs-booticon bs-docs-booticon-lg bs-docs-booticon-outline">自我介绍</span>
<p class="lead">博主主要从事于客户端、嵌入式、移动端的开发工作,酷爱研发,热于分享!</p>
<p class="lead">
<a href="/contact.html" class="btn btn-outline-inverse btn-lg">联系博主</a>
</p>
</div>
</main>
</body>>
</html>>
- 在 views 文件夹下创建 contact.html 文件,作为跳转页面,contact.html 的代码如下:
<!DOCTYPE html>
<html lang="UTF-8">
<head>
<title>
我的博客
</title>>
</head>>
<body class="bs-docs-home">
<!--Docs master nav-->
<header class="navbar navbar-static-top bs-docs-nav" id="top">
<div class="bs-docs-header" id="content" tabindex="-1">
<br class="container">
<h1>联系博主</h1>
<div class="lead">
<address>
<br>电子邮件: <strong>123456789@qq</strong></br>
<br>地址: 上海市嘉定区安亭镇紫金大别墅区36号</br>
<br>邮政编码: 201711</br>
<br><abbr title="Phone">联系电话: </abbr>021-12345678
</address>
</div>
</div>
</header>
- 在 views 同级目录下创建 web_server.py 文件,用于实现客户端和服务器的 http 通信,具体代码如下:
import socket
import re
from multiprocessing import Process
# 设置静态文件根目录
HTML_ROOT_DIR = "./views"
class HTTPServer(object):
def __init__(self):
# 创建 Socket 对象
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def start(self):
# 设置最多连接数
self.server_socket.listen(128)
print("服务器等待客户端连接...")
# 执行死循环
while True:
# 建立客户端连接
client_socket, client_address = self.server_socket.accept()
print("[%s, %s]用户连接上了" % client_address)
# 实例化进程类
handle_client_process = Process(target=self.handle_client, args=(client_socket,))
handle_client_process.start()
client_socket.close()
# 处理客户端请求
def handle_client(self, client_socket):
# 获取客户端请求数据
request_data = client_socket.recv(1024)
print("request data: ", request_data)
# 按照行 ('\r', '\r\n', '\n') 分隔
requset_lines = request_data.splitlines()
for line in requset_lines:
print(line)
# 解析请求报文
request_start_line = requset_lines[0]
print("*" * 10)
print(request_start_line.decode("gbk"))
# 使用正则表达式,提取用户请求的文件名
file_name = re.match(r"\w+ +(/[^ ]*)", request_start_line.decode("utf-8")).group(1)
# 如果文件名是根目录,设置文件名为 file_name
if "/" == file_name:
file_name = "/index.html"
# 打开文件,读取内容
try:
file = open(HTML_ROOT_DIR + file_name, "rb")
except IOError:
response_start_line = "HTTP/1.1 404 Not Found\r\n"
response_headers = "Server: My server\r\n"
response_body = "The file is not found !"
else:
# 读取文件内容
file_data = file.read()
file.close()
response_start_line = "HTTP/1.1 200 OK\r\n"
response_headers = "Server: My server\r\n"
response_body = file_data.decode("utf-8")
# 拼接返回数据
response = response_start_line + response_headers + "\r\n" + response_body
print("response data: ", response)
# 向客户端返回响应数据
client_socket.send(bytes(response, "gbk"))
client_socket.close()
def bind(self, port):
# 绑定端口
self.server_socket.bind(("", port))
def main():
http_server = HTTPServer()
http_server.bind(8000)
http_server.start()
if __name__ == "__main__":
main()
运行 web_server.py 文件,然后使用谷歌浏览器访问 “127.0.0.1:8000/”,得到以下结果:
服务器等待客户端连接...
[127.0.0.1, 55459]用户连接上了
request data: b'GET / HTTP/1.1\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: zh-Hans-CN,zh-Hans;q=0.5\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363\r\nAccept-Encoding: gzip, deflate\r\nHost: 127.0.0.1:8000\r\nConnection: Keep-Alive\r\n\r\n'
b'GET / HTTP/1.1'
b'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
b'Accept-Language: zh-Hans-CN,zh-Hans;q=0.5'
b'Upgrade-Insecure-Requests: 1'
b'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363'
b'Accept-Encoding: gzip, deflate'
b'Host: 127.0.0.1:8000'
b'Connection: Keep-Alive'
b''
**********
GET / HTTP/1.1
response data: HTTP/1.1 200 OK
Server: My server
<!DOCTYPE html>
<html lang="UTF-8">
<head>
<title>
我的博客
</title>>
</head>>
<body class="bs-docs-home">
<!--Docs master nav-->
<header class="navbar navbar-static-top bs-docs-nav" id="top">
<div class="container">
<div class="navbar-header">
<a href="/" class="navbar-brand">我的博客</a>>
</div>
<nav id="bs-navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li>
<a href="https://blog.csdn/qq_34139994/article/details/107725117">Python 进阶之路</a>
</li>
<li>
<a href="https://blog.csdn/qq_34139994/article/details/97393033">Qt 进阶之路</a>
</li>
<li>
<a href="https://blog.csdn/qq_34139994/article/details/104144719">我的网址收藏</a>
</li>
<li>
<a href="https://blog.csdn/qq_34139994/article/details/93847054">设计模式</a>
</li>
<li>
<a href="https://blog.csdn/qq_34139994/article/details/105390364">请善待90后</a>
</li>
<li>
<a href="/contact.html">联系博主</a>
</li>
</ul>
</nav>
</div>
</header>>
<!--Page content of coursel-->
<main class="bs-docs-masthead" id="content" tabindex="-1">
<div class="container">
<span class="bs-docs-booticon bs-docs-booticon-lg bs-docs-booticon-outline">自我介绍</span>
<p class="lead">博主主要从事于客户端、嵌入式、移动端的开发工作,酷爱研发,热于分享!</p>
<p class="lead">
<a href="/contact.html" class="btn btn-outline-inverse btn-lg">联系博主</a>
</p>
</div>
</main>
</body>>
</html>>
[127.0.0.1, 55527]用户连接上了
request data: b'GET /contact.html HTTP/1.1\r\nReferer: http://127.0.0.1:8000/\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: zh-Hans-CN,zh-Hans;q=0.5\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363\r\nAccept-Encoding: gzip, deflate\r\nHost: 127.0.0.1:8000\r\nConnection: Keep-Alive\r\n\r\n'
b'GET /contact.html HTTP/1.1'
b'Referer: http://127.0.0.1:8000/'
b'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
b'Accept-Language: zh-Hans-CN,zh-Hans;q=0.5'
b'Upgrade-Insecure-Requests: 1'
b'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363'
b'Accept-Encoding: gzip, deflate'
b'Host: 127.0.0.1:8000'
b'Connection: Keep-Alive'
b''
**********
GET /contact.html HTTP/1.1
response data: HTTP/1.1 200 OK
Server: My server
<!DOCTYPE html>
<html lang="UTF-8">
<head>
<title>
我的博客
</title>>
</head>>
<body class="bs-docs-home">
<!--Docs master nav-->
<header class="navbar navbar-static-top bs-docs-nav" id="top">
<div class="bs-docs-header" id="content" tabindex="-1">
<br class="container">
<h1>联系博主</h1>
<div class="lead">
<address>
<br>电子邮件: <strong>123456789@qq</strong></br>
<br>地址: 上海市嘉定区安亭镇紫金大别墅区36号</br>
<br>邮政编码: 201711</br>
<br><abbr title="Phone">联系电话: </abbr>021-12345678
</address>
</div>
</div>
</header>
WSGI 接口
WSGI(Web Server Gateway Interface)服务器网端接口,是 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。WSGI 中存在两种角色:接受请求的的 Server(服务器)和处理请求的 Application(应用),它们底层是通过 FastCGI 沟通的。当 Server 收到一个请求后,可以通过 Socket 把环境变量和一个 Callback 回调函数传给后端 Application,Application 在完成页面组装后通过 Callback 把内容返回给 Server,最后 Server 再将响应返回给 Client。
使用 Python 的 wsgiref 模块可以不用考虑服务器和客户端的连接、数据的发送和接收等问题,而专注以业务逻辑的实现。下面通过实例应用 wsgiref 创建页面。
使用上个例子中 views 文件夹下的 index.html 作为主页
在 views 文件夹同级目录下创建 application.py 文件,用于实现 Web 应用程序的 WSGI 处理函数,具体代码如下:
def app(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')]) # 响应信息
file_name = environ['PATH_INFO'][1:] or '/index.html' # 获取 url 参数
HTML_ROOT_DIR = "./views" # 设置 HTML 文件目录
try:
file = open(HTML_ROOT_DIR + file_name, "rb") # 打开文件
except IOError:
response = "The file is not found !" # 如果异常,返回 404
else:
file_data = file.read() # 读取文件内容
file.close() # 关闭文件
response = file_data.decode("utf-8") # 构造响应数据
return [response.encode("utf-8")] # 返回数据
在 views 文件夹同级目录下创建 web_server.py 文件,用于启动 WSGI 服务器,加载 application() 函数,具体代码如下:
from wsgiref.simple_server import make_server # 从 wsgiref 模块导入
from application import app # 导入编写的 application 函数
httpd = make_server("", 8000, app) # 创建一个服务器,IP 地址为空,端口为 8000,处理函数是 app
print("Serving HTTP on port 8000...")
httpd.serve_forever() # 开始监听 HTTP 请求
运行 web_server.py 文件,当显示 “Serving HTTP on port 8000…” 时,在浏览器地址栏输入 “127.0.0.1:8000”,就能访问 index.html 首页啦!
Web 框架
如果你要从零开始建立一些网站,可能会注意到你不得不一次又一次地解决一些相同的问题。这样做是非常麻烦的,并且违反了良好编程的核心原则之一 - DRY(不要重复自己)。
有经验的 Web 开发人员在创建新站点时也会遇到类似的问题。当然,总会有一些特殊情况会因网站而异,但在大多数情况下,开发人员通常需要处理四项任务 - 数据的创建、读取、更新和删除,也称为 CURD。幸运的是,开发人员通过使用 Web 框架解决了这些问题。
Web 框架是用来简化 Web 开发的软件框架。框架的存在是为了避免用户重新发明轮子,并且在创建一个新的网站时帮助减少一些开销。典型的框架提供了如下常用功能:
- 管理路由;
- 访问数据库;
- 管理会话和 Cookies;
- 创建摸版来显示 HTML;
- 促进代码的重用;
事实上,框架根本就不是什么新的东西,它只是一些能够实现常用功能的 Python 文件。我们可以把框架看作是工具的集合,而不是特定的东西。框架的存在使得建立网站更快、更容易。
前面我们学习了 WSGI(服务器网关接口),它是 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。也就是说,只要遵循 WSGI 接口规则,就可以自主开发 Web 框架。所以,各种开源 Web 框架至少有上百个,关于 Python 框架优劣的讨论页仍在继续。
作为初学者,应该选择一些主流的框架来学习,因为主流的框架文档齐全,技术积累较多,社区繁盛,并且能得到更好的支持。下面介绍几种 Python 的主流 Web 框架:
-
Django
这可能是最广为人知和使用最广泛的 Python Web 框架了。Django 有世界上最大的社区和最多的包。它的文档非常完善,并且提供了一站式的解决方案,包括缓存、ORM、管理后台、验证、表单处理等,使得开发复杂的数据库驱动的网站变得简单。但是,Django 系统耦合度较高,替换掉内置的功能比较麻烦,所以学习曲线也相当崎岖; -
Flask
Flask 是一个轻量级 Web 应用框架。它的名字暗示了它的含义,他基本上就是一个微型的胶水框架。Flask 把 Werkzeug 和 Jinja 粘和在一起,所以它很容易被扩展。Flask 也有许多的扩展可以供用户使用,Flask 也有一群忠诚的粉丝和不断增加的用户群。它有一份很完善的文档,甚至还有一份唾手可得的常见范例。Flask 很容易使用,用户只需要几行代码就可以写出来 “Hello World”; -
Bottle
这个框架相对来说比较新。Bottle 才是名副其实的微框架 - 它只有大约 4500 行代码。它除了 Python 标准库以外,没有任何其他的依赖,甚至还有自己独特的一点儿模板语言。Bottle 的文档很详细并且抓住了事物的实质。它很像 Flask,也使用了装饰器来定义路径; -
Tornado
Tornado 不单单是个框架,还是个 Web 服务器。它一开始视为 FriendFeed 开发的,后来在 2009 年的时候也给 Facebook 使用。它是为了解决实时服务而诞生的。为了做到这一点,Tornado 使用了异步非阻塞 IO,所以它的运行速度非常快;
更多请参考
- Python 进阶之路
更多推荐
Python Web 编程
发布评论