微信天气小程序需通过四步实现精确定位:一是在app.json中声明scope.userLocation权限并填写具体desc;二是onLoad中调用wx.getLocation获取gcj02坐标;三是用坐标调用和风geoapi查询精确位置及唯一location ID;四是用ID请求天气数据并拼接省市县地址显示,同时必须添加手动选城兜底逻辑。

微信天气预报小程序要实现精确定位,必须绕过系统默认的粗略城市级定位,直接获取设备真实经纬度并反查精确到街道/社区级别的地理位置信息。这一步做不好,用户看到的永远是“北京市”而不是“朝阳区三里屯街道”。
第一步:在小程序配置中声明位置权限
打开项目根目录下的 app.json 文件,在最外层对象中添加 【permission】 字段。注意不是写在 pages 或 window 下面,否则不生效。
填入以下内容:
"permission": { "scope.userLocation": { "desc": "用于获取您当前所在位置,提供精准天气预报" } }
这句 desc 文字会出现在用户首次授权弹窗里,必须写得具体、可信。写成“获取位置”或“用于服务”会被微信审核驳回。
第二步:调用 wx.getLocation 获取原始坐标
在页面 JS 文件(如 pages/index/index.js)的 onLoad 生命周期中,插入 getLocation 调用:
wx.getLocation({ type: 'gcj02', success: (res) => { console.log('原始坐标:', res.longitude, res.latitude) }, fail: () => { wx.showToast({ title: '定位失败,请检查手机GPS', icon: 'none' }) } })
【type 必须设为 gcj02】,这是国内地图服务(包括和风天气)要求的加密坐标系。如果误用 wgs84,后续城市反查会返回错误城市或空结果。
这一步操作起来很简单,但真机测试时经常失败——原因八成是手机系统级定位开关没开,或者微信未被授予定位权限。iOS 用户尤其要注意在「设置→隐私与安全性→定位服务→微信」里选“使用期间”而非“永不”。
第三步:用坐标调和风天气城市查询API
方法一:直接请求 geoapi.qweather.com/v2/city/lookup
支持AI生成符合公众号规范的图文,推送至草稿箱;兼容其他技能生成的图文/图片。通过向导扫码授权,支持多账号;无需暴露Secret密钥或配置IP白名单。
将上一步拿到的 res.longitude 和 res.latitude 拼成字符串 经度,纬度(注意逗号是英文半角),代入 URL:
https://geoapi.qweather.com/v2/city/lookup?key=你的API_KEY&location=116.4807,39.9896
响应体中的 data.location[0].name 是城市名,adm2 是区/县名,adm3 是街道/乡镇名——这才是真正“精准”的依据。
方法二:用 location ID 替代坐标(推荐用于后续天气请求)
从上一步响应中提取 data.location[0].id(例如 101010100),这个 ID 是和风天气体系内唯一标识该地点的编码。后面所有天气接口(如实时天气、逐小时预报)都必须用它,不能继续传坐标,否则部分接口会报错或返回默认城市数据。
第四步:请求实时天气并渲染到页面
① 构造天气请求 URL:
https://devapi.qweather.com/v7/weather/now?key=你的API_KEY&location=刚拿到的ID
② 在 success 回调中,取 res.data.now.temp 渲染温度,res.data.now.textDay 渲染天气描述,res.data.now.windScale 渲染风力等级。
③ 把 res.data.location.name + res.data.location.adm2 拼成完整地址显示在页面顶部,例如“北京市朝阳区”,而不是只写“北京”。
注意:如果用户关闭了定位或拒绝授权,不要留白或显示“定位中”。必须 fallback 到手动城市选择逻辑——在 WXML 中加一个城市选择器按钮,点击后跳转城市搜索页。这个兜底机制不做,小程序上线审核大概率被拒。


















