ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

uniapp微信小程序真机调试正常但预览/体验版请求失败?域名校验排查指南

uniapp微信小程序真机调试正常但预览/体验版请求失败?域名校验排查指南 用uniapp开发微信小程序真机调试正常、扫码预览和体验版却全部请求失败别慌这篇帮你彻底排查做微信小程序开发最折磨人的一件事就是你本地怎么跑都没问题模拟器ok、真机调试ok结果一扫码预览接口全跪。更离谱的是发布成体验版之后依然请求失败。遇到这种情况十个人里有九个第一反应是后端挂了还有一个已经在改代码准备重写了。先别急着动代码。这个问题的根因十有八九出在你对微信小程序请求域名校验机制的理解上。我接手过不少uniapp项目也踩过这个坑今天就把这个场景完整拆解一遍把根因、排查路径和正确解法讲清楚。这篇文章适合所有正在用uniapp开发微信小程序、尤其是单机调试通过但线上环境请求失败的同学看完能少走很多弯路。1. 项目概述与问题现象还原1.1 开发工具里一切正常线上环境却全线崩溃先描述一下这个问题的典型症状。你正在用HBuilderX写uniapp项目代码里用uni.request去请求后端接口本地开发一切顺利。打开微信开发者工具模拟器里页面数据正常渲染登录、列表、详情页全都好使。然后你觉得差不多了点一下“真机调试”用手机扫码在真机上跑了一遍发现也正常。这时候你信心满满把代码上传生成一个预览二维码用微信扫一扫打开——完蛋页面空白或者数据加载不出来。打开调试面板一看所有请求全是fail。你以为是自己上传的代码有问题再仔细检查一遍代码没变只是从“真机调试”变成了“扫码预览”结果就天壤之别。接着你发布成体验版让同事帮忙测一下结果一样请求全部失败。你让同事打开调试模式看到控制台里报的是request:fail url not in domain list或者errno:600001类似的错误。这时候你才隐约意识到问题可能不在代码而在微信的域名校验机制上。1.2 为什么真机调试正常预览和体验版就不通这里要先搞清楚微信小程序不同运行环境的请求校验差异。模拟器和真机调试走的是“开发模式”这个模式下微信允许你在开发者工具里勾选一个选项——“不校验合法域名、web-view业务域名、TLS版本以及HTTPS证书”。只要这个选项开着你的请求不管请求什么域名、是不是HTTPS、证书有没有问题开发工具都会放行。真机调试为什么也正常因为真机调试本质上是手机连接了你的电脑通过网络把开发者工具的配置同步过去了。微信开发者工具里的“真机调试”并不是真正脱离工具的独立运行它依然借用了开发工具的能力所以那个“不校验合法域名”的开关对真机调试同样生效。这也是很多人误以为“真机验证过了应该没问题”的原因其实真机调试根本没测到真正的线上运行环境。而扫码预览和体验版是完全脱离开发者工具的独立小程序运行实例。微信客户端会严格校验所有请求的域名是否在小程序后台配置的合法域名列表里。只要没配置请求直接失败根本到不了服务器。1.3 这个问题的本质没有理解微信的“域名白名单”机制微信小程序从诞生那天起就对网络请求做了非常严格的限制。所有的wx.request、uni.request、wx.uploadFile、wx.downloadFile请求域名必须在小程序后台提前配置并且必须是HTTPS协议还必须完成ICP备案。这个机制在开发工具里可以通过开关注销但到了真实运行环境就是铁律没有任何商量余地。这个设计的本意是防止小程序请求任意第三方接口保护用户数据安全。但对开发者来说如果前期没有规划好域名或者一直在本地用IP、localhost调试到了打包上线阶段就会被卡住。uniapp项目因为很多人在H5端也一起开发H5端没有这个限制所以更容易忽略微信小程序的这个特殊要求。2. 根因分析开发环境与线上环境的请求链路差异2.1 微信开发者工具的“不校验合法域名”开关既是利器也是陷阱在微信开发者工具的“详情” - “本地设置”里有一个“不校验合法域名、web-view业务域名、TLS版本以及HTTPS证书”的复选选项。这个选项默认是勾上的。它的作用范围覆盖模拟器和真机调试但在预览版和体验版中完全不生效。很多uniapp项目在开发阶段后端接口可能跑在局域网IP、开发机上甚至可能用的还是http而不是https。这种环境下你只能依赖这个开关才能在开发工具里调通接口。问题是一旦把这个状态当成“理所当然”到了发布阶段就会一脚踩空。正确的理解是这个开关只是开发阶段的“临时通行证”它不能代表小程序在真实环境下的表现。真正判断你的小程序能不能请求某一接口只看三件事——域名有没有在后台配置、HTTPS证书是否有效、TLS版本是否满足要求。三者缺一不可。2.2 真机调试的本质藏在“正常”表象下的危险信号很多人对真机调试有一个误解以为真机调试就是在手机上完整地运行小程序。实际上微信开发者工具的真机调试是手机通过USB或者网络连接电脑上的调试服务请求转发链路仍然包含开发者工具。这意味着开发者工具里开着的“不校验合法域名”开关会同样作用于真机调试。这也是为什么会出现“真机调试正常预览版不行”的根本原因。真机调试成功只能说明你的代码逻辑、接口参数、返回数据格式都是对的开发工具到手机这一条调试链路也没问题。但它完全无法验证真实微信客户端请求HTTPS接口时域名的合法性问题。这一点很多人容易忽略我在实战中见过太多团队真机调试一过就以为万事大吉结果预览版一出来就集体傻眼。记住一句话真机调试通过是必要不充分条件它只代表你的业务代码没问题不代表你的小程序能上架、能发布。2.3 预览版与体验版和正式版几乎一样的“硬核校验”扫码预览和体验版都是通过微信客户端直接加载你的小程序代码包。它们是独立于开发者工具运行的所有请求会直接由微信客户端发起并严格执行微信的域名校验策略。这个校验策略和正式发布版本完全一致。所以在预览版和体验版里如果你的请求域名没有配置到小程序后台的合法域名列表中结果就是request:fail url not in domain list。这个错误在开发工具里几乎不会出现因为你开了校验豁免在真机调试里也不会出现因为真机调试同样走了豁免。只有到了预览版、体验版、正式版这个错误才会被暴露出来。这是整个问题最核心的底层逻辑。搞清楚了这一点后面所有的排查和修复就都有了方向。3. 完整解决方案三步配置合法域名3.1 第一步准备域名与HTTPS证书在配置合法域名之前你首先需要一个已经备案的域名并且这个域名必须支持HTTPS访问。微信小程序要求所有请求域名必须是HTTPS并且TLS版本不能低于1.2。如果你手头还没有域名去买一个现在域名价格也不算贵。如果你想省钱用IP地址直接请求那这条路走不通小程序后台配置域名的时候必须填域名不允许填IP。就算你非要在开发阶段用IP到了审核阶段也一样会被驳回。HTTPS证书的获取也很简单。如果用的是阿里云、腾讯云这类云厂商直接在控制台申请免费证书就行一般一年有效到期前记得续期。也可以是Lets Encrypt之类的免费证书只要证书在有效期内微信不会因为证书是免费的就拒绝。实际测试下来各类正规CA签发的证书都能正常通过校验。配置HTTPS时要注意几个细节。第一不要用自签名证书微信客户端不认开发工具里即使勾了不校验也最好别碰这是雷区。第二证书要和域名匹配不能拿A域名的证书放在B域名上。第三服务器需要支持TLS 1.2及以上有些老旧的服务器配置可能只开了TLS 1.0这类服务器在微信小程序里也会报错。3.2 第二步在小程序后台配置服务器域名准备好了域名和证书之后登录微信公众平台进入小程序后台。左边菜单找到“开发管理”点击“开发设置”往下滚动就能看到“服务器域名”这一栏。这里需要配置四类域名域名类型用途示例request合法域名普通HTTPS请求https://api.example.comuploadFile合法域名文件上传https://api.example.comdownloadFile合法域名文件下载https://cdn.example.comsocket合法域名WebSocket连接wss://ws.example.com如果你的项目只是普通接口请求配置request合法域名就够了。如果涉及上传图片、文件还需要配置uploadFile合法域名。下载功能同理需要配置downloadFile合法域名。注意每个域名都必须以https://开头不能带路径、不能带端口号只是单纯的域名。配置完之后一般几分钟之内就会生效。但我在实际工作中遇到过配置完仍然报错的情况等了十几分钟再看就正常了。这个生效过程有延迟不要一配完就急着测试稍微等一会儿。3.3 第三步验证域名白名单是否生效配置完成之后怎么确认真的生效了最直接的方法就是把开发者工具里“不校验合法域名”的开关关掉然后在模拟器里重新跑一下页面。如果关掉开关之后请求仍然正常说明你的域名配置和HTTPS证书都没问题。这一步很多人会漏掉。他们在后台配置完域名不关开发工具的开关直接在模拟器里测当然还是正常的但他们以为这是配置的功劳。实际上只要开关没关你测的仍然是“豁免模式”没有任何参考价值。所以我的建议是开发阶段你可以开着“不校验”开关但每次调整完小程序后台的域名配置之后一定要记得手动关掉这个开关在模拟器里做一次完整的请求验证。关掉开关之后模拟器里的请求行为就等同于真实环境下的请求行为。如果这时候还能通那你发布预览版、体验版基本就稳了。4. 代码侧与工程配置的补充检查4.1 uniapp项目中的baseURL与环境变量管理解决了域名校验的问题还有一个非常容易踩的坑就是uniapp项目里baseURL的配置。很多uniapp项目会同时支持H5端和微信小程序端H5端开发时可能用的是http://localhost:8080或者局域网IP小程序端如果忘记做环境区分就会带着这个开发地址去请求。这个问题在开发工具里大概率不会暴露因为开发者工具默认开启了域名校验豁免。但到了预览版、体验版一旦请求的地址是localhost或者IP微信直接报url not in domain list而且你后台根本没法配置这种地址。所以uniapp项目里必须做好环境的区分。我常用的方式是在项目根目录建一个config.js根据process.env.NODE_ENV或者uni-app内置的编译条件来判断当前环境然后给不同端分配不同的接口地址。微信小程序端必须使用正式的HTTPS域名H5端可以继续用本地地址两者互不干扰。配置示例大致如下let baseURL if (process.env.NODE_ENV development) { // 开发环境 #ifdef H5 baseURL http://localhost:8080 #endif #ifdef MP-WEIXIN baseURL https://api.example.com #endif } else { // 生产环境 baseURL https://api.example.com } export { baseURL }这里有一个uni-app特有的条件编译写法#ifdef MP-WEIXIN和#endif之间的代码只在微信小程序端编译生效H5端不会包含。这个写法在跨端项目中非常实用能有效避免不同端互相污染。4.2 manifest.json和开发者工具中的AppID配置检查还有一个容易忽略的地方就是小程序后台域名配置和当前小程序AppID是否匹配。有时候你会在微信公众平台同时管理多个小程序比如一个测试号、一个正式号或者公司有几个业务小程序。如果你在开发者工具里用的是A小程序的AppID但域名配置在了B小程序的后台那同样请求不通。这种问题排查起来特别隐蔽因为你的域名配置完全正确、HTTPS证书也正常、代码也没问题但就是请求失败。唯一的线索是报错信息里可能会带上校验失败的域名。所以发布之前一定要确认开发者工具里当前项目的AppID是哪个、你在微信公众平台登录的是不是这个小程序、域名配置在哪个小程序下。这三者必须一一对应。uniapp项目里AppID的配置在manifest.json文件的mp-weixin节点中改完记得重新编译。4.3 本地开发中“跳过校验”选项的正确用法虽然前面一直在强调“不校验合法域名”只是临时方案但在日常开发中这个选项确实必不可少。关键是知道什么时候开、什么时候关。我的习惯是日常开发阶段开着。每次涉及接口联调开着这个选项可以省去很多麻烦不管后端是http还是https不管是指定端口还是本地IP都能直接请求。但每次准备打包发布之前我会做一轮“严格模式”自测关掉这个选项用模拟器完整跑一遍核心流程。这一轮自测特别重要它能提前暴露所有域名相关的问题。如果关掉开关后请求失败别急着在代码里找原因先看域名后台配置是否完整、证书是否有问题、请求地址是否用了IP或localhost。基本山80%的问题在这一步就能被拦截下来。不过要特别注意一点关掉“不校验”开关后在开发工具里的报错提示可能不够直接有时控制台只会显示request:fail或者一个errno没有特别指向性的提示。这种情况下建议先在模拟器里用wx.request直接请求一次目标域名或者在浏览器里访问一下这个HTTPS地址确认域名本身能通。如果浏览器也访问不了基本就是域名或证书的问题跟小程序无关。5. 常见问题与排查技巧实录5.1 配置了合法域名之后请求依然失败这是我最常被问到的一类问题。明明后台已经配好了request合法域名开发者工具里关掉“不校验”开关之后依然请求失败。这时候要按顺序排查以下几点。第一检查域名是否备案。微信小程序要求所有合法域名都必须完成ICP备案如果你的域名没有备案配置的时候可能能填进去但请求的时候就会被拦截。第二检查HTTPS证书是否被信任。在浏览器里打开这个接口地址如果浏览器地址栏显示“不安全”或者有证书错误那微信客户端也会拒绝。第三检查服务器是否支持TLS 1.2。微信要求的TLS版本是1.2及以上老旧的服务器默认配置可能是TLS 1.0或1.1需要手动升级。第四检查你是否配置了正确的域名类型。有人以为只要配了request合法域名所有请求就都能通了。其实不然uni.uploadFile需要uploadFile合法域名uni.downloadFile需要downloadFile合法域名。如果你在上传文件时请求失败看看uploadFile域名配了没有。第五检查域名有没有带端口。后台配置合法域名时是不允许带端口号的。如果你的接口地址是https://api.example.com:8080那就超出合法域名校验的范围了请求必挂。这是新手很常见的失误尤其是本地测试用惯了带端口号的地址。5.2 开发工具正常真机调试正常但扫码预览就是挂了这个现象前面已经详细分析过根因就是真机调试借用了开发者工具的“不校验”开关。遇到这种情况不要怀疑手机有问题也不要怀疑代码有问题直接去小程序后台检查域名配置。关于扫码预览还有一个细节值得注意用微信扫一扫打开预览二维码时这个小程序本质上仍然走的是微信客户端的完整校验链路。所以预览版能通过就意味着域名校验这一关已经过了后续发布正式版基本不会在这一块再出问题。另外预览二维码是有时效的一般是15分钟还是30分钟我记不太清了过期的二维码扫了打不开。如果遇到扫了没反应的情况先看看是不是二维码过期了重新生成一个再试。5.3 一个隐蔽的坑接口返回的数据格式和状态码有些时候域名校验已经全部通过了预览版里请求也发出去了但页面依然显示异常。这种情况很容易被误判为“请求失败”实际上请求是成功的只是返回数据的处理出了问题。比如开发工具里接口返回的数据是正常的JSON但到了真机上因为某些字段的数据类型不一致导致前端解析报错。又比如接口返回的HTTP状态码不是200微信开发者工具里会显示请求成功但状态码是302或者500有些逻辑可能会把它当成失败处理。所以我在排查“请求失败”问题时会先区分一下是请求都没发出去还是请求发出去了但返回结果不对。如果是前者大概率是域名校验的问题如果是后者就要打开控制台看具体的返回数据那可能是业务逻辑层面的问题和本文讨论的域名校验没有关系。5.4 关于“代码包上传失败”和“网络请求错误”的区分和本文主题相近但完全不同的另一个问题是上传代码包时提示上传失败网络请求错误。这个错误发生在你点击“上传”按钮把代码提交到微信后台的时候而不是小程序运行时的接口请求。我之前遇到过一位读者他说他的小程序预览版请求不通后面又说他上传代码也失败问我是不是同一个问题。其实这是两码事。上传失败可能是开发者工具的网络问题、代码包大小超过限制、或者微信服务器暂时不稳定。即使你的接口域名校验完全没问题也可能出现上传失败的情况。这里给一个额外的提醒如果代码包超过2MB主包上传也会失败。那时候报的错和网络请求错误很相似但原因就是代码包太大了。需要做分包处理或者压缩资源体积。如果你遇到上传失败先看是不是包大小超了这个比排查网络更快。5.5 一个加速排错的技巧用抓包工具或控制台看请求当所有配置看着都对、代码也没改过但请求就是不通过时建议用抓包工具看一下请求到底发生了什么。开发者工具自带的Network面板就能看不用额外装工具。打开Network面板把“不校验合法域名”的开关关掉然后触发一次请求。如果请求是红色的点开详情看失败原因。如果是url not in domain list那还是域名配置的问题。如果是ERR_CERT_AUTHORITY_INVALID那是证书问题。如果是Failed to connect那就是服务器本身连不上。每一种提示都对应不同的排查方向定位起来比猜要快得多。如果开发者工具里表现和真机表现不一致可以再用手机上的小程序调试面板。预览版和体验版打开调试模式之后同样能看到请求日志和报错信息完全可以定位到具体是哪一步出了问题。5.6 微信小程序请求问题排查速查表错误特征可能原因处理方案url not in domain list域名未配置或配置错误在小程序后台添加request合法域名配置了域名仍然失败域名未备案/证书无效检查ICP备案和HTTPS证书有效性带端口号的域名请求失败合法域名不允许带端口去掉端口或使用默认443端口上传文件失败未配置uploadFile合法域名在后台添加uploadFile合法域名真机调试通、预览版不通真机调试走了开发工具校验豁免后台配置域名后重新预览开发工具通、手机不通手机请求走了真实校验关闭“不校验”开关后重新验证请求返回fail但域名已配置证书TLS版本过低升级服务器TLS到1.2及以上请求发出但页面异常接口返回数据解析问题查看返回数据格式检查业务逻辑6. 习惯养成与避坑心得6.1 开发初期就把域名方案定下来别拖到上线前这个问题的痛苦程度和你在项目哪个阶段遇到它有直接关系。如果你在开发第一天就规划好了正式接口域名并且在小程序后台配置好那么整个开发过程都不会遇到这个坑。但如果你前期完全用localhost和IP调试一直到要发版了才来处理域名问题那可能就要面对换域名、改代码、重新联调等一系列连锁反应。所以我强烈建议项目启动的第一天就把正式环境的域名买好、备案好、证书签好、后台配好。开发阶段可以开“不校验”开关随便请求但正式域名要早早在后台躺好。这样当你准备发布的时候只需要把代码里的接口地址切到正式域名什么都不用折腾。6.2 上线前做一次完整的“严格模式”自测不管你的项目多么简单在准备提交审核或者发布体验版之前都建议做一次严格的域名校验自测。具体做法就是关闭开发者工具的“不校验合法域名”开关在模拟器里把所有涉及网络请求的页面和功能全部走一遍。这一步花不了多少时间但能帮你拦截掉90%以上的域名校验问题。如果你用的接口涉及第三方服务比如地图SDK、支付回调也要一并检查这些域名是否都在后台配置过了。否则可能主流程都正常但某个角落里一个第三方接口请求失败线上用户遇到就麻烦了。6.3 关于多个环境的域名切换如果你的项目有多个环境比如开发环境、测试环境、生产环境建议在代码里通过环境变量来区分接口域名。uniapp项目在打包时可以通过process.env.NODE_ENV来判断当前是开发还是生产再结合条件编译区分不同的平台这样各环境的域名不会乱。我见过有些项目直接在代码里写死了开发环境的接口地址发布到生产之后忘了改结果线上版本请求全部打到开发服务器上数据错乱得一塌糊涂。这种问题比域名校验更隐蔽而且很难排查。用好环境变量把这个风险从根源上消除。6.4 最后再分享一个实用技巧如果你在开发者工具里配置了多个环境地址但不想每次打包都手动改baseURL可以在manifest.json的mp-weixin节点下加自定义字段比如devUrl和prodUrl然后在代码里通过uni.getSystemInfoSync之类的接口去读取。不过这种方式稍微有点冷门我一般还是推荐直接用process.env.NODE_ENV和条件编译结合简单直观团队协作时也不容易扯皮。另外当你确认所有的域名配置、证书都没有问题但预览版在手机上依然请求失败的时候可以尝试把小程序从最近使用列表中删除重新扫码进入。微信客户端对域名配置有一定的缓存虽然正常情况下不需要手动清缓存但遇到这种灵异事件时强杀微信再重开往往能解决问题。做微信小程序开发域名校验这一关绕不过去。踩过一次坑把原理搞清楚以后换项目、换域名、换环境都能快速定位问题。希望这篇总结能帮你省下几小时的排查时间。
返回列表