Postman中PUT请求正常,Deno TypeScript的Fetch请求失败
问题:Postman可正常发送PUT请求,Deno Fresh应用中Fetch发起的同请求失败
我在Postman中发送PUT请求可以成功,但在Deno Fresh应用里用Fetch发起完全相同的PUT请求却失败了。已确认请求体中的key、wallet_address和signature都是非空字符串,但请求依旧失败。
前端Fetch请求代码
async function sendSignature() { const signer = provider.getSigner(); const nonce = "asdf123492fd"; const signatureSigned = await signer.signMessage(nonce); const headers = new Headers({ 'Content-Type': 'application/json' }); const opts = { method: 'PUT', headers: headers, body: JSON.stringify({ key: props.singleUser, wallet_address: walletAddrs, signature: signatureSigned }) } console.log(opts.body); const rawPosts = await fetch('http://localhost:4000/users/kythis1', opts); console.log(rawPosts); }
后端相关代码
入口文件(Oak框架)
import { Application } from "https://deno.land/x/oak/mod.ts"; import { APP_HOST, APP_PORT } from "./config.js"; import router from "./routes.js"; import _404 from "./controllers/404.js"; import errorHandler from "./controllers/errorHandler.js"; import { oakCors } from "https://deno.land/x/cors/mod.ts"; const app = new Application(); app.use(oakCors()); // Enable CORS for All Routes app.use(errorHandler); app.use(router.routes()); app.use(router.allowedMethods()); app.use(_404); console.log(`Listening on port:${APP_PORT}...`); await app.listen(`${APP_HOST}:${APP_PORT}`);
PUT请求控制器
import User from "../db/database.js"; export default async ({ request, response }) => { if (!request.hasBody) { response.status = 400; response.body = { msg: "Invalid user data" }; return; } const body = request.body(); const { key, wallet_address, signature } = JSON.parse(await body.value); console.log(signature); if (!key) { response.status = 422; response.body = { msg: "Incorrect user data. Email and key are required" }; return; } const foundUser = await User.where('key', '=', key).first(); if (!foundUser) { response.status = 404; response.body = { msg: `User with key ${key} not found` }; return; } foundUser.wallet_address = wallet_address; foundUser.updated_at = new Date(); const updatedResp = await foundUser.update(); response.body = { msg: "User updated", updatedResp }; };
路由配置
import { Router } from "https://deno.land/x/oak/mod.ts"; import getUsers from "./controllers/getUsers.js"; import getUserDetails from "./controllers/getUserDetails.js"; import createUser from "./controllers/createUser.js"; import updateUser from "./controllers/updateUser.js"; //import deleteUser from "./controllers/deleteUser.js"; const router = new Router(); router .get("/users", getUsers) .get("/users/:key", getUserDetails) .post("/users", createUser) .put("/users/:key", updateUser); //.delete("/users/:id", deleteUser); export default router;
排查方向与解决方法
1. 路由参数与请求体key不匹配
后端PUT路由定义为/users/:key,意味着应该从URL参数获取用户标识,但当前控制器是从请求体读取key。Postman请求可能是将正确的key放在URL参数中,而前端Fetch的URL参数kythis1与请求体props.singleUser的值不一致,导致查询用户失败。
修正方案:
修改控制器,从路由参数获取key:
export default async ({ request, response }) => { if (!request.hasBody) { response.status = 400; response.body = { msg: "Invalid user data" }; return; } // 从URL路由参数获取key const key = request.params.key; const body = request.body(); // 仅从请求体读取其他字段 const { wallet_address, signature } = JSON.parse(await body.value); console.log(signature); if (!key) { response.status = 422; response.body = { msg: "Incorrect user data. Key is required" }; return; } const foundUser = await User.where('key', '=', key).first(); if (!foundUser) { response.status = 404; response.body = { msg: `User with key ${key} not found` }; return; } foundUser.wallet_address = wallet_address; foundUser.updated_at = new Date(); const updatedResp = await foundUser.update(); response.body = { msg: "User updated", updatedResp }; };
2. CORS预检请求未正确处理
虽然启用了oakCors(),但默认配置可能未允许PUT方法的预检请求。显式配置CORS规则:
app.use(oakCors({ origin: "http://localhost:3000", // 替换为你的Deno Fresh应用地址 methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], allowedHeaders: ["Content-Type"], }));
3. Fetch未处理HTTP错误状态码
Fetch API仅在网络错误时触发reject,HTTP错误状态码(如400、404)不会抛出异常,只会返回ok: false的响应。添加错误处理逻辑:
const rawPosts = await fetch('http://localhost:4000/users/kythis1', opts); if (!rawPosts.ok) { const errorInfo = await rawPosts.json(); console.error('请求失败:', rawPosts.status, errorInfo); return; } const responseData = await rawPosts.json(); console.log('请求成功:', responseData);
4. 请求体JSON解析异常
在后端控制器添加JSON解析错误捕获,避免因请求体格式问题导致失败:
const body = request.body(); let parsedBody; try { parsedBody = JSON.parse(await body.value); } catch (err) { response.status = 400; response.body = { msg: "Invalid JSON format in request body" }; return; } const { wallet_address, signature } = parsedBody;
内容的提问来源于stack exchange,提问作者ChristianOConnor
相关产品推荐
相关产品推荐

