shinnosuke
2026-09-18 131a28347f2c3ce272f61fce425a6eea4fa5e51c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
 * 开发环境服务端地址解析。
 *
 * 背景:后台跑在开发机上,而开发机的局域网 IP 会随网络环境变化(见过 192.168.110.26 与
 * 192.168.110.15)。把 IP 写死在 config/api.uts 里,每次换网都得改代码重新编译,忘了改就
 * 请求到一台不存在的机器上,表现成"登录不上"——从报错里看不出是地址问题。
 *
 * 结论:**不要猜 IP**。微信开发者工具与后台跑在同一台机器上,所以 127.0.0.1 永远可达;
 * 页面来源本身也是 127.0.0.1(见请求的 Referer),因此同源、连跨域都不涉及。
 *
 * 曾试过用 uni.getNetworkType 读本机局域网 IP 自动探测,实测在开发者工具里拿不到 ip
 * (真机上该字段返回的是手机自己的地址,对连开发机也没有帮助),所以放弃这条路。
 *
 * 真机调试:手机访问不了 127.0.0.1。此时用 storage 覆盖即可,不必改代码:
 *   uni.setStorageSync('development-api-base-url', 'http://<开发机局域网IP>:8080')
 * 清了这条 key 就回到开发者工具适用的默认值。
 */
 
/**
 * 开发者工具与本机后台:回环地址,跟网络怎么变无关。
 *
 * 不要写具体局域网 IP(曾经写成 192.168.110.26:8080,别人拉到代码后所有请求都打到那台机器上,
 * 表现成"小程序读不到数据")。127.0.0.1 在开发者工具里永远指向本机后台。
 */
const loopbackDevelopmentBaseUrl = 'http://127.0.0.1:8080'
 
/**
 * 真机调试用的开发机局域网地址:手机上的 127.0.0.1 指手机自己,连不到后台,
 * 必须用开发机的局域网 IP。换网/换 IP 时改这一行即可(也可以在真机调试控制台用下面的 storage 覆盖)。
 */
const lanDevelopmentBaseUrl = 'http://192.168.110.13:8080'
 
/** 覆盖用的 storage key,真机调试时写入开发机局域网地址。 */
const overrideStorageKey = 'development-api-base-url'
 
/**
 * 开发环境基础地址:优先级
 * 1. 真机调试时手动写入的 storage 覆盖值;
 * 2. 微信开发者工具 → 回环地址 127.0.0.1(工具与后台同机,永远可达);
 * 3. 真机 → 开发机局域网地址(手机访问不了 127.0.0.1)。
 */
export const developmentApiBaseUrl = (): string => {
    const override = uni.getStorageSync(overrideStorageKey)
    if (override != null && (override as string).trim().length > 0) return (override as string).trim()
    const info = uni.getSystemInfoSync()
    const platform = info != null && info.platform != null ? '' + info.platform : ''
    if (platform == 'devtools') return loopbackDevelopmentBaseUrl
    return lanDevelopmentBaseUrl
}
 
/**
 * 在 App 启动时调用。这里只做一次记录,方便排查"请求打到哪台机器"。
 */
export const initializeDevelopmentApiBaseUrl = () => {
    console.log('Development API base url: ' + developmentApiBaseUrl())
}