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

在Ky中实现OAuth 1.0结合React Query时数据始终为undefined的问题排查

在Ky中实现OAuth 1.0结合React Query时数据始终为undefined的问题排查

从你的描述来看,Postman能正常拿到数据、WooCommerce返回200状态码和产品数组,但React Query里数据始终是undefined,说明问题大概率出在客户端的响应解析、Schema校验或者错误处理环节,而非OAuth签名逻辑本身(毕竟签名成功才会得到200和数据)。咱们一步步来排查:

1. 先排查Schema解析的问题(最可能的原因)

你的fetchAll方法直接用productSchema.parse(response),如果Schema定义和WooCommerce返回的产品结构不匹配(比如某个必填字段缺失、类型不匹配),parse会直接抛出异常。而如果你的代码没有捕获这个异常,React Query会把请求标记为失败,data字段就会是undefined,但错误信息会被存在error属性里(你可能没注意到)。

临时修改代码排查:

给fetchAll加上错误捕获和日志,用safeParse代替parse来直观看到解析问题:

export const ProductServices = {
  fetchAll: async () => {
    try {
      const response = await wooApiV3.get(`products`).json();
      // 先打印原始响应,确认和Postman返回的结构一致
      console.log('Raw WooCommerce Response:', response);
      
      // 用safeParse避免直接抛出异常,查看解析结果
      const parseResult = productSchema.safeParse(response);
      if (!parseResult.success) {
        console.error('Schema解析失败:', parseResult.error);
        throw new Error('产品数据格式校验失败');
      }
      
      return parseResult.data;
    } catch (err) {
      console.error('获取产品列表出错:', err);
      throw err; // 抛出错误让React Query捕获
    }
  },
};

运行后看控制台日志:

  • 如果Raw WooCommerce Response和Postman里的一致,那就是Schema的问题,需要调整productSchema让它匹配WooCommerce的产品结构(比如允许可选字段、调整字段类型)。
  • 如果控制台有Schema解析错误,根据错误信息修改Schema即可。

2. 检查Ky的请求配置是否存在冲突

你的Ky实例在beforeRequest钩子中修改了extendedOptions.searchParams,有可能和Ky的内置参数处理逻辑冲突。可以试试直接修改request.url而非设置searchParams:
修改beforeRequest钩子的最后部分:

// 替换原来的 extendedOptions.searchParams = existingParams;
url.search = existingParams.toString();
request.url = url.toString();

这样更直接地修改请求URL的查询参数,避免Ky的参数合并逻辑可能带来的问题。

另外,确认你的ExtendedOptions类型是否正确包含了searchParams字段,避免类型错误导致参数没有被正确传递。

3. 确认React Query的使用逻辑

检查你调用ProductServices.fetchAll的React Query代码,确保没有忽略错误:

const { data, error, isLoading } = useQuery({
  queryKey: ['products'],
  queryFn: ProductServices.fetchAll,
});

// 渲染时检查错误
if (isLoading) return <div>加载中...</div>;
if (error) return <div>出错了: {(error as Error).message}</div>;
// 再渲染data

如果之前没有处理error状态,可能会忽略掉Schema解析或请求抛出的错误,误以为数据是undefined。

4. 验证OAuth签名的边缘情况(可选)

虽然Postman能拿到数据,但可以临时在generateOAuthSignature里打印baseString和signingKey,和Postman生成的对比,确保签名逻辑完全一致:

export const generateOAuthSignature = (
  method: string,
  url: string,
  params: Record<string, string>,
  consumerSecret: string
): string => {
  const sortedParams = Object.keys(params)
    .sort()
    .map(
      key =>
        `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
    )
    .join('&');
  const baseString = [
    method.toUpperCase(),
    encodeURIComponent(url),
    encodeURIComponent(sortedParams),
  ].join('&');
  console.log('OAuth Base String:', baseString); // 和Postman对比
  console.log('Signing Key:', `${encodeURIComponent(consumerSecret)}&`);

  const signingKey = `${encodeURIComponent(consumerSecret)}&`;
  const hash = CryptoJS.HmacSHA1(baseString, signingKey);
  return CryptoJS.enc.Base64.stringify(hash);
};

如果和Postman生成的base string一致,说明签名逻辑没问题,可以排除这部分原因。

总结

最可能的根源是Schema解析失败,因为你已经确认WooCommerce返回了有效数据,只要解决Schema和返回结构不匹配的问题,或者捕获解析错误,就能解决数据undefined的问题。

备注:内容来源于stack exchange,提问作者Milos N.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 10:53:08