forked from EduCraft/curriculum-project-hub
50ddf32cc2
该端点不读 body,但调用方(curl -d、Postman、部分 HTTP 客户端)常给空 POST 自动带上 Content-Type。Fastify 默认只有 JSON parser,遇到别的媒体类型在解析 阶段就以 415 FST_ERR_CTP_INVALID_MEDIA_TYPE 拒掉,进不到 handler。 修法是给它一个丢弃 body 的 catch-all parser,**封装在自己的 register 作用域 内**。不能加到外层实例上:admin plugin 没有 fastify-plugin 封装,那样会让全站 每个 POST/PUT/PATCH 都接受 form-urlencoded。而 form-urlencoded 是跨站 HTML form 唯一能发出的媒体类型(application/json 会触发 CORS preflight),"只认 JSON"本身是一层 CSRF 纵深防御 —— 当前 sameSite=lax 还挡着,但不该为这个端点 全局放掉。 两处细节: - "*" 只兜没有专属 parser 的媒体类型。内建 JSON parser 优先级更高,空 body 会 被它判成 FST_ERR_CTP_EMPTY_JSON_BODY(400),故在本作用域内一并覆盖。 - 用 parseAs:"string" 让 Fastify 读完流(否则连接不释放),而非手写 payload.resume()。 前端未改 —— 原本不带 Content-Type 的发法一直是 204,是正确的。 测试 5 个 case,最后一个是护栏:断言作用域外的 POST 路由发 form-encoded 仍为 415,防止以后有人把 parser 提到外层。