uni.request params 无效修复记录(user-binding+list-by-patient).md 4.2 KB

uni.request params 无效修复记录 — user-binding/list-by-patient

概要 ✅

在使用 uni.request 向后端请求 POST /user-binding/list-by-patient 时,尝试通过 params 传递 query 参数无效,问题被定位为 uni.request 并不会将 params 自动拼接到 url(或该项目的环境未实现该字段),最终采用在 URL 中拼接 Query String(qs)并 encodeURIComponent 编码后成功解决。


问题描述 ⚠️

src/api/userBinding.ts 中最初写法:

const res: any = await uni.request({
  url: 'https://wx.baiyun.work/user-binding/list-by-patient',
  method: 'POST',
  data: query,
  params: {
    patientUserId,
    bindingType
  },
  header: {
    'content-type': 'application/json',
    Authorization: `Bearer ${token}`
  }
})

希望 params 被自动拼接到 URL(比如 ?patientUserId=...&bindingType=...),但实践中该字段没有生效,于是后续改为把 query 直接放到 URL:

const qs = `?patientUserId=${encodeURIComponent(String(patientUserId))}&bindingType=${encodeURIComponent(bindingType)}`
const res: any = await uni.request({
  url: 'https://wx.baiyun.work/user-binding/list-by-patient' + qs,
  method: 'POST',
  data: query,
  header: { ... }
})

这样一来后端成功收到了查询字符串,接口返回正常。


为什么会这样?💡

  • uni.request 支持的参数与 axios/fetch 不完全一致。某些平台/版本在 uni.request 中并不会自动把 params 拼接到 URL(尤其是在 POST 请求中,Get请求中可能是生效的),或者该 SDK 在实现上没有 params 字段(或仅在特定平台生效)。
  • 后端在 list-by-patient 端点可能通过 @RequestParam(Spring)、query 参数或路由匹配等方式读取 query,因此必须把参数放到 URL 中。
  • 另外要注意:Snowflake 等 64 位 ID 要用字符串传递以避免 JavaScript Number 精度问题(项目中已有处理)。

建议与最佳实践 🔧

  1. 简单而稳妥的解决方法:在 url 上手动拼接 qs
    • 使用 encodeURIComponent 对参数进行编码,避免空格或特殊字符破坏查询字符串。
  2. 如果你期望 params 自动生效:
    • 查看当前 uni-app SDK 版本与平台(H5、小程序、App)文档,确认 params 是否被支持和如何使用。某些平台可能不支持把 params 自动序列化到 URL。
  3. 后端改造建议(如果可能):
    • 考虑将 list接口改为 GET 请求(更语义化),或同时支持从 body 和 query 中读取参数(兼容性更好)。
  4. 推荐封装函数:

    • 为了避免每次都手写拼接字符串,封装一个通用的构建 URL 的工具:

      function toQueryString(obj: Record<string, any>) {
      return Object.entries(obj)
      .filter(([, v]) => v !== undefined && v !== null)
      .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
      .join('&')
      }
      
      // 使用示例
      const qs = toQueryString({ patientUserId, bindingType })
      const res = await uni.request({
      url: `https://wx.baiyun.work/user-binding/list-by-patient?${qs}`,
      method: 'POST',
      data: query,
      header: {...}
      })
      
  5. 记录与测试:

    • 在改动后,通过前端控制台或后端日志确认实际 hit 的 URL;
    • 通过单元/集成测试模拟该请求,确保在不同平台(H5/小程序/APP)上行为一致;
    • 如果使用 CORS,确保后端对 query 参数和 Authorization header 的处理没有冲突。

项目里与此相关的注意点 🧭

  • src/api/userBinding.ts 已用字符串处理 Snowflake ID(String(patientUserId)) 防止精度丢失;保持该写法即可。
  • 当需要批量拼接多个可选参数时,确保 toQueryString 过滤掉 undefined / null 值。

结论 ✅

问题的根本在于:uni.requestparams 字段在该平台/项目里没有把参数自动拼接到 URL 上。稳妥且简单的修复是:在 URL 中手动拼接 querystring(使用 encodeURIComponent),或者改后端接口/规范。该修复已被验证成功。


如需我把 toQueryString 工具函数也写入 src/utils/ 并替换所有类似拼接,请回复,我可以继续实现并加上对应的单元测试。