You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用时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()); // 允许所有跨域请求,可根据需求配置具体规则

其他次要问题

  1. 服务器中const variables = await req.body.profile多余了await,req.body是同步获取的,直接去掉await即可。
  2. 原服务器的POST接口未给客户端返回响应,需要在then和catch中添加res.status().json(),否则客户端会一直处于等待状态。
  3. 客户端响应处理错误:直接JSON.parse(response)是错误的,应该使用response.json()方法解析JSON格式的响应体。

内容的提问来源于stack exchange,提问作者VictorAtoms

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 10:20:40