Lab2 · 购物清单(Flask REST API)
一句话:把 Lab1 的购物清单改造成 Flask REST API + fetch 前端渲染——服务器只返回 JSON,页面由 JS 负责渲染和局部刷新,不再整页重载。 1. getseparatedshoppinglist()…
代码:
CSSE280 HW\280lab2\|所属课程:CSSE280 总览|前身:Lab1 - 购物清单(Socket 手写服务器)
一句话:把 Lab1 的购物清单改造成 Flask REST API + fetch 前端渲染——服务器只返回 JSON,页面由 JS 负责渲染和局部刷新,不再整页重载。
相比 Lab1 的三大变化
| Lab1 | Lab2 | |
|---|---|---|
| 服务器 | socket 手写 | Flask(@app.get / @app.post 装饰器) |
| 数据模型 | 两个 list | 一个 dict:{"milk": {"got": False}, ...},移动 = 翻转 got 标志 |
| 渲染 | 服务端 str.format + 整页刷新 | 前端 fetch JSON → renderLists() 操作 DOM |
API 设计
| 方法 | 路由 | 作用 | 状态 |
|---|---|---|---|
| GET | /list | 返回整个清单 JSON | ✅ 已注册 |
| POST | /list/<item> | 添加条目(防重复),返回 201 | ✅ 已注册 |
| PATCH | /list/<item> | 移动条目(翻转 got) | ⚠️ 前端在调,服务器没注册 |
| DELETE | /list/<item> | 删除条目 | ⚠️ 前端在调,服务器没注册 |
⚠️ 当前的坑(跑之前要修)
get_separated_shopping_list()不存在:httpserver.py的 GET/POST 路由调用了它,但dataservice.py里只有get_shopping_list()→ 一访问/list就AttributeError。前端parseListsFromResponseDataDict()期望的就是原始 dict 格式,所以直接改调get_shopping_list()即可。- PATCH / DELETE 路由缺失:
script.js的moveItem/removeItem会收到 405。需要补@app.patch("/list/<item>")和@app.delete("/list/<item>"),分别调dataservice.move_item_between_lists/remove_item。 httpserver.py底部的handle_api_routes()是 Lab1 手写路由的残留死代码(写在app.run()之后,永远不会被 Flask 调用),可删——但它恰好是第 2 条 PATCH/DELETE 该怎么写的参考。
前端要点(script.js)
- 四个操作统一模式:
fetch(url, options)+async/await+response.ok检查 +try/catch - 每次操作后服务器回完整清单 JSON,前端全量重绘(
innerHTML = ''再 append)——简单粗暴但不会状态漂移 - 删除按钮
event.stopPropagation():阻止点"X"时冒泡触发<li>的"移动"点击事件 parseListsFromResponseDataDict()用Object.keys().filter()把 dict 按got标志拆成两个数组- Loading 提示:请求期间显示
Loading...,渲染完加loadingHide类隐藏
运行
cd "CSSE280 HW\280lab2"
.venv\Scripts\activate # venv 里装了 Flask 3.1.3
python httpserver.py
# → http://localhost:8080/shopping.html
.venv/是 Python 虚拟环境(Flask 及依赖),属于工具不属于知识,笔记不收录其内容。