微信小程序 wx.uploadFile 上传失败:合法域名、临时路径与 HTTPS 证书排查

典型现象:wx.chooseImage / wx.chooseMedia 能选出本地图,一点上传就失败。控制台常见 uploadFile:fail、url not in domain list、ssl hand shake error,或 success 回调里 statusCode 不是 200。选图正常、预览正常,问题几乎都在「上传通道」而不是业务表单本身。

下面按「先读完整 errMsg → 再核对 uploadFile 合法域名 → 再核 filePath → 再核 HTTPS/证书 → 再看服务端响应」走。每一步都能在开发者工具或后台核对。

0. 先分清失败发生在哪一层

wx.uploadFile 失败至少有三层,处理路径不同:

  1. 客户端直接 fail:域名未配置、非法 URL、临时文件失效、网络中断;
  2. 请求发出去了,但 TLS/证书握手失败:HTTPS 证书链、SNI、中间人代理;
  3. HTTP 层有响应,但业务失败 :statusCode 4xx/5xx,或 body 里业务码非成功。

先在 fail 回调里把完整 errMsg 打出来,不要只弹「上传失败」。再在 success 里始终打印 statusCode 与 data 前几百字符------很多「上传失败」其实是服务端 413/401,客户端却进了 success。

javascript 复制代码
wx.uploadFile({
  url: 'https://api.example.com/upload',
  filePath: tempFilePath,
  name: 'file',
  formData: { biz: 'avatar' },
  success(res) {
    console.log('statusCode', res.statusCode, 'data', res.data);
  },
  fail(err) {
    console.error('uploadFile fail', err);
  }
});

1. uploadFile 合法域名必须单独配

小程序后台 开发 → 开发管理 → 开发设置 → 服务器域名 里,request 合法域名和 uploadFile 合法域名是两套。只配了 request、没配 uploadFile,真机上传必挂。

核对清单:

  1. 打开后台,确认上传接口的 主机名 (不含 path)已写入 uploadFile 合法域名;
  2. 协议必须是 https://,且与代码里的 url 主机名完全一致(含是否带 www);
  3. 改完域名后,开发者工具点 详情 → 域名信息 刷新,或重新编译;真机需重新预览/体验版;
  4. 本地调试若勾了「不校验合法域名」,真机/体验版不会自动放行------以真机结果为准。

常见坑:把完整 path 写进域名列表(应只写主机)、把 IP 当域名、把测试环境域名留在正式版未同步。

2. 临时路径有时效:选完立刻传

chooseImage / chooseMedia 返回的 tempFilePaths / tempFiles[].tempFilePath 是本地临时文件,不是永久 URL。

  1. 选完立刻 uploadFile ,不要先 setData 存几天再传;
  2. 页面卸载、热重载、长时间停留后再传,临时文件可能已失效,表现为 file not found 类 fail;
  3. 需要二次使用时,先上传拿到服务端 URL,业务层只存远端地址;
  4. 多图上传用队列串行或有限并发,避免同一 tempFilePath 被并发读导致偶发失败。

验证:fail 时把 filePath 打日志,确认不是空字符串、不是远端 http 地址、也不是过期后的旧 path。

3. URL、name、header 与 formData

接口约定不对时,客户端可能「看起来成功」但服务端没收文件:

  1. url 必须是完整 HTTPS 地址;
  2. name 要与服务端表单字段名一致(常见是 file / upload);改错字段名时,部分框架返回 200 + 业务错误;
  3. 需要鉴权时把 token 放进 header(如 Authorization),不要塞进文件名;
  4. formData 只放字符串键值;不要把对象/数组直接塞进去而不序列化;
  5. 不要手动设 Content-Type: multipart/form-data 且自拼 boundary------让运行时生成。

4. HTTPS 证书与握手

ssl hand shake error / ERR_CERT_* 类错误,按下面查:

  1. 浏览器或 openssl s_client -connect host:443 -servername host 看证书是否过期、链是否完整;
  2. 证书域名是否覆盖你实际请求的主机(含多域名证书的 SAN);
  3. 服务器是否只开了 TLS1.0/过时套件------以微信客户端当前要求为准;
  4. 公司代理/抓包工具若在开发机中间人,开发者工具可能偶发过、真机不过;真机请关代理再试。

证书修好后,先用同一 URL 在手机浏览器打开确认可访问,再回小程序上传。

5. 服务端 statusCode 与体积限制

客户端进了 success 仍可能业务失败:

现象 优先查
statusCode 401/403 鉴权 header、登录态过期
statusCode 404 上传 path 写错、网关路由
statusCode 413 Nginx client_max_body_size、网关 body 限制
statusCode 500 服务端落盘权限、对象存储密钥
data 非 JSON / 业务码失败 字段名 name、文件类型白名单

图片过大时:上传前用 wx.compressImage 或自有压缩,再传;同时把服务端与网关的 body 上限对齐(例如都 ≥ 5MB),避免「工具里小图过、真机大图 413」。

6. 最小复现核对表

按顺序勾:

  1. 后台 uploadFile 合法域名 是否含该主机;
  2. 真机是否仍勾着仅开发工具生效的「不校验合法域名」错觉;
  3. filePath 是否为本次选择返回的临时路径;
  4. url 是否 HTTPS 且主机与白名单一致;
  5. success 里 statusCode 是否 200,data 业务是否成功;
  6. 同 URL 用 curl/Postman multipart 能否上传成功(隔离小程序与服务端问题)。

每改一轮:清缓存 → 重新编译 → 真机预览再传一张。用日志里的 errMsg / statusCode 验证,不要凭感觉连点重试。


本文由 DEVDIY 整理。我们日常主要做 WordPress / Shopify 外贸站与微信小程序的开发和线上排查,把这类上传失败问题拆成可复现步骤,方便自己和同行对照。

原文/延伸阅读:https://devdiy.cn/miniprogram/

相关推荐
李纲明14 小时前
WordPress 打开页面直接报 500 而不是白屏:先核伪静态与文件权限,再查服务器错误日志
nginx·wordpress·文件权限·伪静态·错误日志·devdiy·500错误
李纲明20 小时前
WordPress 更新插件后按钮没反应或表单结账突然失效:先留日志与备份,再按二分法定位冲突插件
wordpress·二分法·插件冲突·devdiy·debug.log·health check·更新插件
李纲明1 天前
微信小程序次卡跨店对不上账或前台随手改余次:先核流水只增不改与统一日切,再查冲正权限与总部只读
微信小程序·devdiy·核销流水·跨店次卡·日切对账·冲正权限·总部只读
李纲明1 天前
微信小程序维修拆机后口头加价或未确认就开工:先核验机快照与报价确认,再查补充报价与取机核验
微信小程序·devdiy·维修验机·报价确认·报价快照·补充报价·取机核验
wx1qq1com1 天前
一桩带几台车:共享租赁桩位配比、取电与结算闭环设计
物联网·微信小程序·小程序
李纲明1 天前
WooCommerce 加购后购物车是空的或结账串了会话:先核页面缓存排除与会话 Cookie,再查 CDN 与对象缓存前缀
cdn·页面缓存·购物车·woocommerce·对象缓存·devdiy·会话cookie
李纲明1 天前
微信小程序场地长租月底对不上或口头占场撞场:先核合约预约与核销流水出账,再查附加费与转租归属
微信小程序·devdiy·场地长租·月结账单·核销流水·附加费·转租归属
2401_879692511 天前
微信小程序照相与摄像功能实现——chooseImage 与 chooseVideo 详解
微信小程序·小程序·notepad++
律宏阔2 天前
微信小程序 + Taro + TDesign 去掉 [&&&],让普通 Tailwind 类接管局部样式
前端·微信小程序·taro
律宏阔2 天前
微信小程序 + Taro + 多语言实现与国际化检查实录
前端·微信小程序·taro