用HTML构建API:返回纯文本的服务器
搭建一个服务端网页服务非常简单:通过HTTP请求返回格式化的纯文本HTML。这种基础且可靠的方法无需额外依赖,浏览器会自动完成所有复杂的渲染工作。
以下是一个使用内置 http.server 模块的极简Python服务器。它对任何GET请求都返回静态HTML页面:
from http.server import BaseHTTPRequestHandler, HTTPServer
WEBPAGE = "<h1>Python网页!</h1>\n"
class HTMLServer(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(str.encode(WEBPAGE))
webServer = HTTPServer(("localhost", 8080), HTMLServer)
print("服务器运行在 http://localhost:8080")
webServer.serve_forever()
使用 curl 命令,你会看到干净的原始文本输出:
$ curl localhost:8080
<h1>Python网页!</h1>
在浏览器中,<h1> 标签会被正确渲染为标题样式。你还可以加入CSS来美化页面:
WEBPAGE = """
<style>
body {
background-color: lightblue;
font-family: 'Comic Sans MS', cursive;
}
</style>
<h1>Python网页!</h1>
"""
浏览器会立即应用这些样式——无需额外步骤。
渲染是浏览器的任务
服务器只负责生成文本;真正的渲染由浏览器完成:解析HTML生成DOM,计算样式,布局排版,并按正确的DPI、字距和度量值应用字体。这个多阶段过程包括解析、样式计算、布局和绘制。
渲染涉及复杂的排版知识——从点(pt)转像素,到处理升部和降部高度。浏览器已为你处理了全部细节。
HTML生成本质上只是字符串操作。不必引入诸如“服务端渲染”这类听起来复杂却不必要的术语。
用HTML表达数据
任何数据都可以通过简单的字符串模板转换为HTML。以下是一个纽约市五个行政区的例子:
boroughs = [
"布朗克斯区",
"曼哈顿",
"布鲁克林",
"皇后区",
"史坦顿岛"
]
LIST = "<li>".join(boroughs)
WEBPAGE = "<h1>纽约市行政区</h1><ul><li>" + LIST + "</ul>"
浏览器能正确解析这段代码——即使没有闭合的 </li> 标签(HTML5对此非常宽容)。
同样适用于JSON格式:
LIST = '","'.join(boroughs)
WEBPAGE = '{ "nyc_boroughs": ["' + LIST + '"] }'
此时HTML更具优势:它原生支持超媒体功能——如链接和表单,无需依赖客户端JavaScript。
- 基于字符串的HTML生成优势:
- 无需库,可在任意编程语言中使用。
- 开销极小。
- 易于调试:curl 可直接查看原始输出。
- 跨平台兼容(bash、awk、Python等)。
HTML API vs JSON API
不妨称之为 HTML API:服务器返回的是HTML而非JSON。浏览器充当客户端,自动解析超媒体内容。
对比:
HTML:
<h1>纽约市行政区</h1>
<ul>
<li>布朗克斯区
<li>曼哈顿
<li>布鲁克林
<li>皇后区
<li>史坦顿岛
</ul>
JSON:
{
"nyc_boroughs": [
"布朗克斯区",
"曼哈顿",
"布鲁克林",
"皇后区",
"史坦顿岛"
]
}
HTML同时包含数据与展示逻辑;而JSON仅传递数据,需客户端额外编写逻辑进行渲染。
生产环境中的模板引擎
对于实际应用,建议使用Jinja2等模板引擎。它们提供自动转义、循环、继承和结构化支持。
以Jinja为例:
<h1>纽约市行政区</h1>
<ul>
{% for borough in boroughs %}
<li>{{ borough }}
{% endfor %}
</ul>
- 模板引擎的核心优势:
1. 自动HTML转义,防止XSS攻击。
2. 可复用片段(局部模板)。
3. 语言原生语法支持(如Htmx支持Rust、Zig)。
4. 无状态设计,便于测试与调试。
5. 无需SPA式的“水合”开销。
与React不同,后者在客户端将JSON“水合”为DOM,模板引擎则在服务端直接生成完整渲染后的HTML。
最关键的几点
- 服务器输出的是HTML文本,浏览器负责渲染。
- HTML API传递的是超媒体,而非原始JSON数据。
- 字符串操作无需框架即可跨语言运行。
- 模板引擎提升安全性和结构清晰度。
- 此方法可轻松适配任何编程语言。
— Editorial Team
暂无评论。