Python 构建 HTTP 服务器的8个步骤

开发 后端 服务器
本文详细介绍了如何使用 Python 构建一个基本的 HTTP 服务器,并逐步介绍了更高级的功能,包括处理静态文件、POST 请求以及路由。

在当今互联网时代,几乎所有的应用程序都需要与服务器交互。Python 提供了多种方式来构建 HTTP 服务器,其中最简单的方法是使用标准库中的 http.server 模块。本文将详细介绍如何使用 Python 构建一个基本的 HTTP 服务器,并逐步介绍更高级的功能。

步骤1:安装Python环境

前提条件:

  • 确保你的计算机上已安装 Python 3.x 版本。
  • 可以访问命令行工具(如 Windows 的 CMD 或 PowerShell,Mac 和 Linux 的 Terminal)。

验证安装:

python --version

输出应类似于 Python 3.10.6。

步骤2:创建项目目录

为了更好地组织代码,建议为项目创建一个新的目录:

mkdir my_http_server
cd my_http_server

步骤3:编写基本HTTP服务器

我们将从一个非常简单的 HTTP 服务器开始,它能接收请求并返回固定的响应。

创建文件 server.py:

from http.server import BaseHTTPRequestHandler, HTTPServer

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.end_headers()
        message = "Hello, World!"
        self.wfile.write(message.encode())

def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler):
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    print(f"Starting httpd server on {server_address[0]}:{server_address[1]}")
    httpd.serve_forever()

if __name__ == "__main__":
    run()

解释:

  • 导入模块:从 http.server 导入 BaseHTTPRequestHandler 和 HTTPServer 类。
  • 定义处理程序类:SimpleHTTPRequestHandler 继承自 BaseHTTPRequestHandler。
  • 实现 do_GET 方法:当接收到 GET 请求时执行。
  • 发送响应:设置状态码为 200(表示成功),然后发送响应体。
  • 运行服务器:run 函数初始化服务器并在端口 8000 上监听。

步骤4:启动服务器

在命令行中运行以下命令:

python server.py

你会看到类似下面的输出:

Starting httpd server on 0.0.0.0:8000

现在,打开浏览器并访问 http://localhost:8000,你应该能看到 “Hello, World!” 这个消息。

步骤5:处理静态文件

目前我们的服务器只能返回固定的字符串。接下来,让我们修改服务器,使其能够处理静态文件,例如 HTML、CSS 和 JavaScript 文件。

修改 server.py 文件:

import os
from http.server import BaseHTTPRequestHandler, HTTPServer

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/':
            filename = 'index.html'
        else:
            filename = self.path[1:]

        try:
            with open(filename, 'rb') as file:
                content = file.read()
                self.send_response(200)
                self.end_headers()
                self.wfile.write(content)
        except FileNotFoundError:
            self.send_error(404, "File Not Found")

def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler):
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    print(f"Starting httpd server on {server_address[0]}:{server_address[1]}")
    httpd.serve_forever()

if __name__ == "__main__":
    run()

解释:

  • 处理路径:如果路径是 /,则默认返回 index.html 文件;否则,返回路径后面的文件名。
  • 读取文件:尝试打开指定路径的文件,并读取其内容。
  • 发送响应:如果文件存在,则发送状态码 200 并返回文件内容;如果文件不存在,则发送状态码 404。

创建静态文件:

在项目目录中创建以下文件:

  • index.html
  • style.css
  • script.js

index.html 示例:

<!DOCTYPE html>
<html>
<head>
    <title>My Simple HTTP Server</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>Hello, World!</h1>
    <p>Welcome to my simple HTTP server.</p>
    <script src="script.js"></script>
</body>
</html>

style.css 示例:

body {
    font-family: Arial, sans-serif;
    background-color: #f0f0f0;
}

h1 {
    color: blue;
}

script.js 示例:

console.log("This is a simple script.");

启动服务器:

在命令行中运行以下命令:

python server.py

打开浏览器并访问 http://localhost:8000,你应该能看到页面显示 “Hello, World!” 并且样式和脚本也正常加载。

步骤6:处理 POST 请求

接下来,我们将让服务器支持处理 POST 请求。这通常用于接收表单数据或其他用户输入。

修改 server.py 文件:

import os
from http.server import BaseHTTPRequestHandler, HTTPServer

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/':
            filename = 'index.html'
        else:
            filename = self.path[1:]

        try:
            with open(filename, 'rb') as file:
                content = file.read()
                self.send_response(200)
                self.end_headers()
                self.wfile.write(content)
        except FileNotFoundError:
            self.send_error(404, "File Not Found")

    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        self.send_response(200)
        self.end_headers()
        response = f"Received: {post_data.decode('utf-8')}"
        self.wfile.write(response.encode())

def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler):
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    print(f"Starting httpd server on {server_address[0]}:{server_address[1]}")
    httpd.serve_forever()

if __name__ == "__main__":
    run()

解释:

  • 读取 POST 数据:获取请求头中的 Content-Length 字段,然后读取相应长度的数据。
  • 发送响应:设置状态码为 200,并返回接收到的数据。

创建表单页面:

修改 index.html 文件,添加一个简单的表单:

<!DOCTYPE html>
<html>
<head>
    <title>My Simple HTTP Server</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>Hello, World!</h1>
    <p>Welcome to my simple HTTP server.</p>
    <form action="/" method="POST">
        <label for="message">Message:</label>
        <input type="text" id="message" name="message">
        <button type="submit">Send</button>
    </form>
    <script src="script.js"></script>
</body>
</html>

启动服务器:

在命令行中运行以下命令:

python server.py

打开浏览器并访问 http://localhost:8000,填写表单并提交,你会看到服务器返回的内容。

步骤7:处理路由

在实际应用中,我们需要根据不同的 URL 路径来处理不同的请求。我们可以使用简单的条件语句来实现这一点。

修改 server.py 文件:

import os
from http.server import BaseHTTPRequestHandler, HTTPServer

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/':
            filename = 'index.html'
        elif self.path == '/about':
            filename = 'about.html'
        else:
            filename = self.path[1:]

        try:
            with open(filename, 'rb') as file:
                content = file.read()
                self.send_response(200)
                self.end_headers()
                self.wfile.write(content)
        except FileNotFoundError:
            self.send_error(404, "File Not Found")

    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        self.send_response(200)
        self.end_headers()
        response = f"Received: {post_data.decode('utf-8')}"
        self.wfile.write(response.encode())

def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler):
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    print(f"Starting httpd server on {server_address[0]}:{server_address[1]}")
    httpd.serve_forever()

if __name__ == "__main__":
    run()

解释:

  • 处理路由:根据不同的路径,返回不同的文件。这里添加了一个新的路径 /about,返回 about.html 文件。

创建 about.html 文件:

<!DOCTYPE html>
<html>
<head>
    <title>About Us</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>About Us</h1>
    <p>This is the about page of our simple HTTP server.</p>
    <script src="script.js"></script>
</body>
</html>

启动服务器:

在命令行中运行以下命令:

python server.py

打开浏览器并访问 http://localhost:8000/about,你会看到关于页面的内容。

步骤8:使用框架简化开发

虽然手动编写 HTTP 服务器可以学习很多底层知识,但在实际开发中,我们通常会使用现成的框架来简化开发过程。Flask 是一个非常流行的轻量级 Web 框架,非常适合快速开发。

安装 Flask:

pip install flaskpip install flask

创建 Flask 应用:

创建一个名为 app.py 的新文件:

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/about')
def about():
    return render_template('about.html')

@app.route('/submit', methods=['POST'])
def submit():
    message = request.form.get('message')
    return f"Received: {message}"

if __name__ == '__main__':
    app.run(port=8000)

解释:

  • 导入模块:从 Flask 导入 Flask、render_template 和 request。
  • 定义路由:使用装饰器 @app.route 来定义不同的路由。
  • 渲染模板:使用 render_template 渲染 HTML 模板。
  • 处理 POST 请求:使用 request.form 获取表单数据。

启动 Flask 服务器:

在命令行中运行以下命令:

python app.py

打开浏览器并访问 http://localhost:8000,你会看到页面内容。填写表单并提交,你会看到服务器返回的内容。

总结

本文详细介绍了如何使用 Python 构建一个基本的 HTTP 服务器,并逐步介绍了更高级的功能,包括处理静态文件、POST 请求以及路由。最后,还展示了如何使用 Flask 框架简化开发过程。通过这些步骤,读者可以掌握构建 HTTP 服务器的基本方法,并了解如何进一步扩展其功能。

责任编辑:赵宁宁 来源: 手把手PythonAI编程
相关推荐

2019-08-22 15:26:24

HTTP服务器Python

2019-07-04 15:00:32

PythonHTTP服务器

2019-10-12 10:00:17

Linux服务器网络

2018-01-17 10:28:34

JavaHttp Server服务器

2010-05-19 16:50:43

IIS服务器

2011-03-29 15:30:20

Zabbix服务器

2010-09-14 14:01:55

ubuntu tftp

2018-02-07 10:45:19

2019-12-26 10:52:06

服务器

2018-03-01 10:45:25

HTTP服务器程序

2010-03-31 10:05:40

CentOS Samb

2017-11-10 08:58:49

Web服务器应用程序

2018-10-09 09:28:12

HTTPHTTP协作服务器

2010-08-05 13:40:06

NFS服务器

2010-08-23 10:40:59

DHCP服务器

2009-07-03 13:05:47

JSP HTTP服务器

2019-04-24 15:06:37

Http服务器协议

2009-12-25 12:17:47

2010-01-12 12:07:28

2023-01-05 09:15:40

点赞
收藏

51CTO技术栈公众号