走一遍提交

👁️ 1 人浏览 💬 0 人评论 ❤️ 添加收藏

(每道题开头都有同一段:上面那个应用的全部源码——render 把标题和正文塞进页面骨架 PAGElist_html / form_html 生成列表和表单,STATIC 是静态文件表,handle 是入口。判题机不联网,题里直接调 handle。)

贯穿全条的应用(留言板):

handle(method, url, body, notes) → (状态码, 头, 正文)
/              GET   200  首页:留言列表 + 发表表单
/about         GET   200  关于页
/notes/<n>     GET   200  第 n 条的详情;越界 404
/api/notes     GET   200  application/json {"count": n, "notes": [...]}
/add           POST  303  Location: /(正文 text 追加进 notes);空文本 400;GET 405
/static/...    GET   文件(只有 style.css);没有 404
其余           404

POST 一条、再 POST 一条空的、再 GET 首页,看状态码和留言数:

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>")

SAMPLE = ["第一条留言", "今天天气不错", "<b>不许</b>"]

notes = list(SAMPLE)
a = handle("POST", "/add", "text=%E6%96%B0%E7%9A%84", notes)
b = handle("POST", "/add", "text=+++", notes)
c = handle("GET", "/", "", notes)
print(str(a[0]) + ":" + a[1]["Location"] + "/" + str(b[0]) + "/" + str(len(notes)) + "/" + str("新的" in c[2]))
提交你的答案
请登录后提交答案。
去登录
代码编辑器
Ctrl + Enter 运行
本次输入:
输出:

                        
👩‍🏫
AI
💬 题目评论

全部评论