调用时req.body为空:Shopify GraphQL动态传参问题求助
问题:Shopify GraphQL变更服务器无法获取客户端POST请求体
搭建了一个用于Shopify店铺GraphQL变更操作的服务器,此前运行正常。但现在从客户端动态传递变量时,尽管网络面板显示已发送对应的请求载荷,服务器端却获取到空的req.body。预期能在请求体中获取profile参数并传入GraphQL变更操作,但实际得到空对象。
服务器代码
const bodyParser = require('body-parser'); const express = require('express') const Shopify = require('shopify-api-node'); const shopify = new Shopify({ shopName: shopName, apiKey: apiKey, password: password }); const app = express(); const port = 3000; app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) app.get('/', (req, res) => { res.send('Hello World!'); }); app.post('/create-shipping-profile', async (req, res) => { console.log(req.body) try{ const variables = req.body.profile // 移除多余的await const query = `mutation deliveryProfileCreate($profile: DeliveryProfileInput!) { deliveryProfileCreate(profile: $profile) { profile { zoneCountryCount name } userErrors { field message } } }`; shopify .graphql(query, variables) .then((result) => { console.log(result); res.status(200).json(result); // 给客户端返回响应 }) .catch((err) => { console.error(err); res.status(500).json({error: err.message}); }); }catch(error){ console.log(error); res.status(500).json({error: error.message}); } }); app.listen(port, () => { console.log(`Server listening on port ${port}`); });
客户端代码
async function postData(url = "", data = {}) { try { const response = await fetch(url, { method: "POST", // 移除no-cors模式,改为服务器端配置CORS cache: "no-cache", headers: { "Content-Type": "application/json", }, redirect: "follow", referrerPolicy: "no-referrer", body: JSON.stringify(data), // 将对象序列化为JSON字符串 }); return await response.json(); // 正确解析JSON响应 } catch (err) { console.log(err); throw err; } } let data = { "profile": { "name": "render created", "locationGroupsToCreate": [ { "locations": [ "gid://shopify/Location/76352618802" ], "zonesToCreate": [ { "countries": [ { "code": "MX", "includeAllProvinces": true } ], "methodDefinitionsToCreate": [ { "active": true, "description": "", "name": "Creado desde render", "rateDefinition": { "price": { "amount": "999", "currencyCode": "MXN" } } } ], "name": "admin" } ] } ] } }; postData("https://deliveryprofiles.onrender.com/create-shipping-profile", data) .then((result) => { console.log(result); }) .catch(err => console.log(err));
问题排查与解决方案
核心问题1:客户端请求体未序列化
客户端fetch的body直接传入了对象data,但fetch要求body必须是字符串、FormData等可序列化类型。直接传对象会被浏览器转换为[object Object]字符串,服务器的body-parser.json()无法解析,导致req.body为空。
修复:将body: data改为body: JSON.stringify(data),把JavaScript对象序列化为JSON字符串。
核心问题2:使用mode: "no-cors"限制请求
no-cors模式会强制浏览器发起"不透明请求",此时浏览器会限制请求头的发送(比如Content-Type: application/json可能被强制改为text/plain),服务器的body-parser.json()无法识别请求体格式,自然解析为空。同时该模式下客户端无法读取响应内容,后续的响应解析会报错。
修复:移除mode: "no-cors",如果存在跨域问题,在服务器端配置CORS:
// 先安装cors依赖:npm install cors const cors = require('cors'); app.use(cors()); // 允许所有跨域请求,可根据需求配置具体规则
其他次要问题
- 服务器中
const variables = await req.body.profile多余了await,req.body是同步获取的,直接去掉await即可。 - 原服务器的POST接口未给客户端返回响应,需要在
then和catch中添加res.status().json(),否则客户端会一直处于等待状态。 - 客户端响应处理错误:直接
JSON.parse(response)是错误的,应该使用response.json()方法解析JSON格式的响应体。
内容的提问来源于stack exchange,提问作者VictorAtoms
相关产品推荐
相关产品推荐

