填一次模板
骨架不动,只往两个空槽里填
每一页都是同一副骨架
(每道题开头都有同一段:上面那个应用的全部源码——render 把标题和正文塞进页面骨架 PAGE,list_html / form_html 生成列表和表单,STATIC 是静态文件表,handle 是入口。判题机不联网,题里直接调 handle。)
用 render 填一个标题里带尖括号的页面,看标题和正文各怎么处理:
import html
import json
from urllib.parse import urlparse, parse_qs
PAGE = "<!doctype html><html><head><meta charset=\"utf-8\"><title>{title}</title><link rel=\"stylesheet\" href=\"/static/style.css\"></head><body><h1>{title}</h1>{body}</body></html>"
def render(title, body):
return PAGE.replace("{title}", html.escape(title)).replace("{body}", body)
def list_html(notes):
if not notes:
return "<p>还没有留言</p>"
return "<ul>" + "".join("<li>" + html.escape(n) + "</li>" for n in notes) + "</ul>"
def form_html():
return "<form method=\"post\" action=\"/add\"><input name=\"text\"><button>发表</button></form>"
STATIC = {"/static/style.css": ("text/css", "h1 { color: #2563eb; }\n")}
def handle(method, url, body="", notes=None):
notes = [] if notes is None else notes
u = urlparse(url)
path = u.path
if path in STATIC:
if method != "GET":
return 405, {"Content-Type": "text/html"}, "<p>只能 GET</p>"
ctype, content = STATIC[path]
return 200, {"Content-Type": ctype}, content
if path.startswith("/static/"):
return 404, {"Content-Type": "text/html"}, "<p>没有这个文件</p>"
if path == "/":
return 200, {"Content-Type": "text/html"}, render("留言板", list_html(notes) + form_html())
if path == "/about":
return 200, {"Content-Type": "text/html"}, render("关于", "<p>一个用标准库写的留言板。</p>")
if path.startswith("/notes/"):
tail = path[len("/notes/"):]
if not tail.isdigit() or not 1 <= int(tail) <= len(notes):
return 404, {"Content-Type": "text/html"}, render("没有这条", "<p>没有这条留言</p>")
return 200, {"Content-Type": "text/html"}, render("第 " + tail + " 条", "<p>" + html.escape(notes[int(tail) - 1]) + "</p>")
if path == "/api/notes":
return 200, {"Content-Type": "application/json"}, json.dumps({"count": len(notes), "notes": notes}, ensure_ascii=False)
if path == "/add":
if method != "POST":
return 405, {"Content-Type": "text/html"}, "<p>请用表单提交</p>"
text = parse_qs(body).get("text", [""])[0].strip()
if not text:
return 400, {"Content-Type": "text/html"}, "<p>留言不能为空</p>"
notes.append(text)
return 303, {"Content-Type": "text/html", "Location": "/"}, ""
return 404, {"Content-Type": "text/html"}, render("找不到", "<p>没有这个页面</p>")
page = render("A<B", "<p>正文</p>")
print(str("<title>A<B</title>" in page) + "/" + str("<h1>A<B</h1>" in page) + "/" + str("<p>正文</p>" in page) + "/" + str(page.count("{")))
全部评论