调用Scryfall API返回HTML而非JSON的问题排查
问题分析与解决方案
核心问题
- 请求体格式错误:后端向Scryfall API发送请求时,
body直接传入JavaScript对象,未序列化为JSON字符串。Scryfall无法解析该格式请求,返回400错误及HTML格式的错误页面,导致后续res.json()解析失败,抛出Unexpected token <错误。 - 错误处理逻辑缺陷:现有
catch分支未正确处理响应体,可能导致响应体被多次读取,触发"The body has already been consumed"错误。
修复步骤
1. 修正后端请求的请求体格式
修改后端fetch的body参数,使用JSON.stringify()将对象转为JSON字符串:
router.post('/scryfall/collection', (req, res) => { const identifiers = req.body.identifiers; console.log(identifiers); let url = 'https://api.scryfall.com/cards/collection'; fetch(url, { method: 'POST', headers: { "Accept": "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ "identifiers": identifiers }) }) .then(apiRes => { // 先校验响应状态,非成功状态抛出错误 if (!apiRes.ok) { throw new Error(`Scryfall API返回错误: ${apiRes.status}`); } return apiRes.json(); }) .then((out) => { res.json(out); }) .catch(err => { console.error(err); res.status(400).json({ error: err.message }); }); });
2. 完善错误处理流程
- 在解析JSON前通过
apiRes.ok判断响应是否成功,避免对错误响应执行json()解析。 - 统一错误捕获逻辑,避免重复处理响应体,同时将错误信息返回前端,方便排查问题。
3. 验证请求格式
确保前端传入的identifiers完全符合Scryfall API要求,例如每个标识符对象包含id/name/set等合法字段,且格式正确。
额外排查提示
若问题仍存在,可在后端catch中添加代码读取错误响应的文本内容,查看Scryfall返回的具体错误详情:
.catch(async (err) => { console.error(err); if (err.response) { const errorText = await err.response.text(); console.error("Scryfall错误详情:", errorText); res.status(400).json({ error: err.message, details: errorText }); } else { res.status(500).json({ error: err.message }); } });
内容的提问来源于stack exchange,提问作者ProgFroz
相关产品推荐
相关产品推荐

