仅使用标准库创建 Web 服务器

Create web server using ONLY standard library

我想在 Python 中仅使用 std 库实现一个网页。

我已经在 PHP 中完成了,但我想在 Python 中完成,而且我很难理解文档。

这是我在 PHP 中所做的:

访问http://localhost:8888/project/src/car.php

用户必须填写一份表格,其中指定汽车品牌。
然后站点 returns JSON 汽车列表 http://localhost:8888/project/src/car.php?brand=toyota
它工作得很好。

在 PHP 中非常容易,但我在 Python 中找不到仅使用标准库的方法。
你有什么建议吗?

这是我目前所拥有的:

server.py:

import http.server
import socketserver

if __name__ == '__main__':
    PORT = 8888
    Handler = http.server.SimpleHTTPRequestHandler
    with socketserver.TCPServer(("", PORT), Handler) as httpd:
        print("serving at port", PORT)
        httpd.serve_forever()

index.html:

<!-- used to make a form for the user -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Autocompletion</title>
</head>
<body>
<h2>Manufacturer finder</h2>

<p>
    Please enter your research
</p>

<form action="car.py" method="get" class="form-example">
    <div class="form-example">
        <label for="brand">Enter your query: </label>
        <input type="text" name="brand" id="brand" required>
    </div>
    <div class="form-example">
        <input type="submit" value="Submit">
    </div>
</form>

</body>
</html>

用户登录 index.html 需要填写表格。当用户完成表单时,这将打开文件:http://localhost:8888/car.py?brand=toyota

该脚本在 http://localhost:8888/ and not http://localhost:8888/car.py 中有效(我的 PHP 脚本也是如此),但这不是问题。

表单填写后,我不知道如何从品牌中检索变量制造商并显示汽车列表。在 car.py 中,我有一个我需要的每个品牌的汽车列表,所以我只需要从品牌中获取正确的汽车并将其打印为 JSON,而无需额外的 HTML。

我遇到的问题:完成表格只是打印整个 car.py 文件。

表单不安全并不是问题(您可以通过将 ?brand=toyota 附加到 url 来获得结果)。

这是我启动服务器的方式:

python server.py

你有什么建议吗?
感谢您的关注

The documentation for the handler class you've chosen 说得很清楚

This class serves files from the current directory and below, directly mapping the directory structure to HTTP requests.

这就是您看到 car.py 内容的原因。

您必须实现自己的处理程序 class,派生自 BaseHTTPRequestHandler,以满足您的需要。当您访问 /data.

时,这个简单的示例仅将查询字符串 returns 解析为 JSON

顺便说一句,比较 PHP 和 Python 这里 ("it was easy in PHP") 是苹果和橘子;使用 PHP,你还有一些东西(可以是 Apache、Nginx、PHP-FPM、PHP 的内置 Web 服务器)来处理请求并选择要使用的脚本,调用它等,其中您正在从头开始做所有事情。

import urllib.parse
import http.server
import socketserver
import json


class CarHandler(http.server.SimpleHTTPRequestHandler):
    def _send_content(self, data, status=200, content_type="text/plain"):
        if isinstance(data, str):
            data = data.encode("utf-8")
        self.send_response(status)
        self.send_header("Content-Type", content_type)
        self.send_header("Content-Length", str(len(data)))
        self.end_headers()
        self.wfile.write(data)
        self.wfile.flush()

    def do_GET(self):
        url = urllib.parse.urlparse(self.path)
        if url.path == "/":
            return self._send_content(
                "<form method=get action=/data><input type=search name=q><input type=submit></form>",
                content_type="text/html",
            )
        elif url.path == "/data":
            qs = urllib.parse.parse_qs(url.query)
            return self._send_content(json.dumps(qs), content_type="application/json")
        else:
            return self._send_content(f"404: {url}", status=400)


if __name__ == "__main__":
    PORT = 8891
    with socketserver.TCPServer(("", PORT), CarHandler) as httpd:
        print("serving at port", PORT)
        httpd.serve_forever()