在JavaScript(Remix框架)中如何同时检查响应状态并获取返回数据?
问题
时隔许久重新在个人项目中使用JavaScript,当前用Remix框架对接独立后端。在发起创建用户这类POST请求时,希望既能验证请求是否成功,又能获取后端返回的响应数据——比如创建记录后,后端会返回带自动分配ID的新记录,方便跳转到对应文档页面。
但现在的实现里响应数据“消失”了。我理解是因为response.ok会处理Promise,之后再尝试访问response.id时,响应已经被“清空”。想问怎么重构代码,先验证状态再分支处理?总觉得先等Promise完成再处理的方式有点繁琐。
代码示例:
export async function action({ request }: ActionArgs) { const body = await request.formData(); // 构造要提交的document对象 const response = await fetch("http://backend:8000/documents/create", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(document) }); if (response.ok) { const documentId = response.id; return redirect("/documents/" + documentId); } else if (response.status == 400) { errors.document = "Document creation failed"; } return json({ errors }); }
解决方案
核心问题是你误解了response.ok的作用——它只是个布尔值,不会消耗响应体。真正的问题是你直接访问response.id的方式错误,后端返回的JSON数据需要通过response.json()解析,这个方法会返回Promise,且调用后响应体就会被读取(不能重复读取)。
重构思路很直接:先判断响应状态,再按需解析响应体,用await处理完全不繁琐,反而逻辑更清晰。
修正后的代码:
export async function action({ request }: ActionArgs) { const body = await request.formData(); const errors = {}; // 提前初始化errors对象,避免未定义报错 // 构造要提交的document对象 const document = { /* 填入你的文档数据 */ }; const response = await fetch("http://backend:8000/documents/create", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(document) }); if (response.ok) { // 解析后端返回的JSON响应体,得到完整的创建后文档数据 const createdDocument = await response.json(); // 从解析后的对象中取出ID const documentId = createdDocument.id; return redirect(`/documents/${documentId}`); } else if (response.status === 400) { errors.document = "Document creation failed"; } else { // 补充处理其他错误状态,比如服务器内部错误 errors.document = "Server error, please try again later"; } return json({ errors }); }
关键说明:
response.ok仅用于判断响应状态码是否在200-299区间,不会触发响应体读取,不存在“清空”问题。- 后端返回的JSON数据必须通过
await response.json()解析成JavaScript对象后,才能访问id这类属性。 - 提前初始化
errors对象,避免未定义导致的运行时错误。 - 用模板字符串拼接跳转路径比字符串拼接更简洁易读。
内容的提问来源于stack exchange,提问作者josephkibe
相关产品推荐
相关产品推荐

