修改 Apple 网络定位(gs-loc)返回坐标 · 支持 Surge / Quantumult X / Loon / Stash · 快捷指令一键设置/恢复定位
10,287
stars
46
commits
JavaScript
primary language
Sep 4, 2026
updated
修改 Apple 网络定位服务 (WiFi/基站) 返回的坐标,实现 iOS 网络定位虚拟定位。打开在线选点页面选位置即可生效,无需手动填经纬度。
⚠️ iOS 27 beta 6 起,系统已禁止对
gs-loc.apple.com/gs-loc-cn.apple.com进行 MITM 拦截,本项目在这些版本上无法使用。实测(beta 8)确认限制发生在 TLS 证书校验层:
locationd仍然正常走系统代理,请求确实到得了中间人,但它会拒绝任何非 Apple CA 签发的证书 —— 即使该 CA 已在「证书信任设置」里打开完全信任(同一台设备、同一张 CA 拦截其他域名是成功的)。由于校验发生在设备内部的
locationd进程中,改用软路由 / 网关侧透明代理 / 换其他 MITM 工具同样无效 —— 这些方案改变的只是流量路径,而问题出在路径终点。完整测试数据见 #113。目前只能停留在受影响版本之前的系统。
Surge: https://raw.githubusercontent.com/Yu9191/wloc/refs/heads/main/modules/wloc.sgmodule
Quantumult X: https://raw.githubusercontent.com/Yu9191/wloc/refs/heads/main/modules/wloc.conf
Loon: https://raw.githubusercontent.com/Yu9191/wloc/refs/heads/main/modules/wloc.lpx
Stash: https://raw.githubusercontent.com/Yu9191/wloc/refs/heads/main/modules/wloc.stoverride
Shadowrocket(小火箭): https://raw.githubusercontent.com/Yu9191/wloc/refs/heads/main/modules/wloc.module
Egern 可直接使用 Surge 模块 Stash 请直接订阅上面的
.stoverride,无需用 Script Hub 转换
默认模块已覆盖目前已知的完整 WLOC 域名集合:
gsp-ssl.ls.apple.combluedot.is.autonavi.combluedot.is.autonavi.com.gds.alibabadns.com直接用快捷指令切换 / 清除定位,无需打开选点页面:
用法
支持苹果地图、高德(含短链,自动跟跳转 + GCJ-02→WGS84 坐标换算)。
前提:代理已开 + 模块已启用 + 信任
gs-loc.apple.com。选点页面(Worker / Pages)方案仍保留,见下方。
为了让苹果地图和高德走同一条流程,链接统一发给 wloc-spoofer.wloc.workers.dev/api/parse 解析:
Location 头里,且是 GCJ-02 偏移坐标。快捷指令既读不到跳转头、也难做坐标换算,所以由 worker 跟跳转 → 抠坐标 → GCJ-02→WGS84 → 返回经纬度。coordinate=纬度,经度,但在中国大陆同样是 GCJ-02 偏移坐标,所以和高德一样由 worker 做 GCJ-02→WGS84 换算后返回;境外坐标会自动跳过换算(out_of_china 判断)原样返回。除了统一坐标系,走同一接口也方便统一处理短链、文本夹链接、名称解码等。隐私: /api/parse 是纯转发解析——收到链接 → 跟跳转 → 解析坐标 → 返回 JSON,全程不写任何存储、不记日志、不缓存,处理完即丢(wrangler.jsonc 里已显式关闭 observability)。跟跳转时只接受 http/https,单次请求 8 秒超时、只读响应正文前 512 KB。
不放心可自行部署: worker 源码完全开源,可自己部署一份替换上面的地址:
worker/src/index.jsworker/src/parse.jsworker/src/page.js、worker/src/gcj-browser.jswloc-spoofer.wloc.workers.dev 换成你自己的 worker 域名即可。解析逻辑带一套不联网的回归测试,改动后跑一下:
cd worker && npm install && npm test
坐标系说明: 页面内部一律以 WGS84 为准。底图切到「高德」时,瓦片画的是 GCJ-02 地物,与 Leaflet 的 WGS84 像素映射差着一个偏移量(深圳一带约 600 米),页面会在 选点/落点时自动双向换算,所以在任意底图上点选得到的都是同一个 WGS84 坐标。
各家地图的坐标系不同,换算按「来源 × 地区」分派:
| 来源 | 中国大陆 | 港澳台 |
|---|---|---|
| 苹果地图 / Google | GCJ-02,需换算 | WGS84,不换算 |
| 高德 / 百度 | GCJ-02 / BD-09,需换算 | 同左,仍需换算 |
港澳台建议优先用苹果或高德的链接。 百度在港澳台的分享短链,坐标要靠网页脚本
带反爬令牌去查,服务端取不到;变通办法是在浏览器打开该链接,等地址栏变成
map.baidu.com/poi/名称/@数字,数字,19z 之后复制整条地址再粘贴——但百度的针脚位置
与苹果/高德常有几十到两百米的出入(大陆约 5 米,港澳台可达 240 米),精确定位时
不建议用它。
支持 Apple Maps / Google Maps / 高德 / 百度 / 坐标文本 链接解析。
iOS 26/27 及更高版本注意: Apple 从 iOS 26 开始大幅强化了
locationd的定位缓存机制,系统会将之前获取的真实定位结果缓存在内存中并长时间复用。这意味着安装模块或切换目标坐标后,即使脚本已成功修改了 WLOC 响应(日志显示"已修改"),系统仍可能继续使用缓存中的旧坐标,导致定位看起来没有变化。解决方法:重启设备。 重启会清空
locationd的内存缓存,系统重新发起 WLOC 请求时会拿到修改后的坐标。飞行模式开关、关闭定位服务等方式在 iOS 26+ 上无法清除此缓存,必须重启。iOS 15~18 通常不需要重启即可生效。
高版本系统推荐操作流程(成功率最高):
方法一:
方法二:
选点页面 → fetch gs-loc.apple.com/wloc-settings/save?lon=x&lat=y
→ 代理模块拦截 → wloc-settings.js 写入 $persistentStore
→ 下次 WLOC 触发 → wloc.js 读取坐标 → patch protobuf 响应
模块包含两条规则:
wloc.js — 拦截 /clls/wloc 响应,解析 protobuf 并替换坐标wloc-settings.js — 拦截 /wloc-settings/save 请求,写入持久化存储| 参数 | 说明 | 默认值 |
|---|---|---|
| longitude | 目标经度(在线选点优先) | null (透传) |
| latitude | 目标纬度(在线选点优先) | null (透传) |
| accuracy | 精度(米) | 25 |
| randomRadius | 扰动半径(米),每次定位在目标点周围随机偏移,0=关闭 | 0 |
| logLevel | 日志级别 | info |
优先级: 在线选点储存 > 模块参数 > 默认值
扰动半径说明: 启用后每次定位响应会在目标坐标周围指定米数内随机偏移,避免每次定位结果完全相同。Surge/Loon/Stash/Shadowrocket 可在模块参数中设置;QX 用户可通过选点页面设置。默认 0(关闭),不影响现有用户。
方法一:关闭或删除模块(推荐)
关闭模块后脚本不再拦截 WLOC 请求,系统自动恢复真实定位。iOS 26+ 需要重启设备清除定位缓存。
方法二:清除持久化数据(透传模式)
清除已保存的坐标后,脚本进入透传模式——不修改 WLOC 响应,直接放行原始数据,系统自动恢复真实 GPS 定位。
透传模式触发条件: 持久化数据为空(null)且模块参数为默认值(113.94114, 22.544577)时,脚本判定用户未自定义坐标,自动跳过修改。模块默认参数无需更改,仅清除持久化数据即可触发透传。
在代理工具中删除持久化数据,字段名为 wloc_settings:
$persistentStore.write(null, "wloc_settings")$prefs.removeValueForKey("wloc_settings")$persistentStore.write(null, "wloc_settings")清除后重启设备即可恢复真实定位。无需关闭模块,脚本会自动检测到无自定义坐标并跳过修改。
注意: 如果用户在模块参数中手动修改了经纬度(非默认 113.94114, 22.544577),即使清除持久化数据,脚本仍会使用模块参数中的坐标进行修改。只有保持默认参数不变时,清除持久化数据才会进入透传模式。
在线选点页面支持收藏多个位置,方便来回切换:
数据存储说明:
localStorage(仅用于选点页面的 UI 便捷操作)$persistentStore(脚本运行时实际读取的数据)两者独立存储。收藏列表是浏览器端的辅助数据,清除浏览器缓存或换浏览器后需重新收藏,但不影响已储存到设备的生效坐标。
公共选点页面有请求上限,建议部署自己的实例:
https://wloc-spoofer.wloc.workers.dev/https://wloc-pages.pages.dev/一键部署(Workers):
一键部署仅支持 Workers 模式,点击按钮后按提示授权即可完成部署。
手动部署(Workers):
# 1. 克隆仓库
git clone https://github.com/Yu9191/wloc.git
cd wloc/worker
# 2. 安装依赖
npm install
# 3. 登录 Cloudflare(首次需要)
npx wrangler login
# 4. 部署
npm run deploy
部署成功后会得到你自己的 Worker 地址(如 https://wloc-spoofer.<你的子域名>.workers.dev),用这个地址选点即可。
免费账户每天 10 万次请求,个人使用完全够用。
Pages 部署不支持一键按钮,需要手动执行:
git clone https://github.com/Yu9191/wloc.git
cd wloc/worker
npm install
npm run pages:deploy
必须走
npm run pages:deploy(它带-c wrangler.pages.jsonc)。直接跑wrangler pages deploy dist会丢掉配置里的 compatibility 设定。
部署时会提示设置 production branch,输入 main 即可。部署成功后得到 https://<项目名>.pages.dev 地址。
Pages 和 Workers 功能完全一致,按需选择即可。
gs-loc.apple.com 和 gs-loc-cn.apple.com本项目采用 AGPL-3.0 许可证。未经授权,禁止将本项目代码用于商业产品或上架应用商店。
JavaScript
100.0%
修改 Apple 网络定位(gs-loc)返回坐标 · 支持 Surge / Quantumult X / Loon / Stash · 快捷指令一键设置/恢复定位
10,287
stars
46
commits
JavaScript
primary language
Sep 4, 2026
updated
修改 Apple 网络定位服务 (WiFi/基站) 返回的坐标,实现 iOS 网络定位虚拟定位。打开在线选点页面选位置即可生效,无需手动填经纬度。
⚠️ iOS 27 beta 6 起,系统已禁止对
gs-loc.apple.com/gs-loc-cn.apple.com进行 MITM 拦截,本项目在这些版本上无法使用。实测(beta 8)确认限制发生在 TLS 证书校验层:
locationd仍然正常走系统代理,请求确实到得了中间人,但它会拒绝任何非 Apple CA 签发的证书 —— 即使该 CA 已在「证书信任设置」里打开完全信任(同一台设备、同一张 CA 拦截其他域名是成功的)。由于校验发生在设备内部的
locationd进程中,改用软路由 / 网关侧透明代理 / 换其他 MITM 工具同样无效 —— 这些方案改变的只是流量路径,而问题出在路径终点。完整测试数据见 #113。目前只能停留在受影响版本之前的系统。
Surge: https://raw.githubusercontent.com/Yu9191/wloc/refs/heads/main/modules/wloc.sgmodule
Quantumult X: https://raw.githubusercontent.com/Yu9191/wloc/refs/heads/main/modules/wloc.conf
Loon: https://raw.githubusercontent.com/Yu9191/wloc/refs/heads/main/modules/wloc.lpx
Stash: https://raw.githubusercontent.com/Yu9191/wloc/refs/heads/main/modules/wloc.stoverride
Shadowrocket(小火箭): https://raw.githubusercontent.com/Yu9191/wloc/refs/heads/main/modules/wloc.module
Egern 可直接使用 Surge 模块 Stash 请直接订阅上面的
.stoverride,无需用 Script Hub 转换
默认模块已覆盖目前已知的完整 WLOC 域名集合:
gsp-ssl.ls.apple.combluedot.is.autonavi.combluedot.is.autonavi.com.gds.alibabadns.com直接用快捷指令切换 / 清除定位,无需打开选点页面:
用法
支持苹果地图、高德(含短链,自动跟跳转 + GCJ-02→WGS84 坐标换算)。
前提:代理已开 + 模块已启用 + 信任
gs-loc.apple.com。选点页面(Worker / Pages)方案仍保留,见下方。
为了让苹果地图和高德走同一条流程,链接统一发给 wloc-spoofer.wloc.workers.dev/api/parse 解析:
Location 头里,且是 GCJ-02 偏移坐标。快捷指令既读不到跳转头、也难做坐标换算,所以由 worker 跟跳转 → 抠坐标 → GCJ-02→WGS84 → 返回经纬度。coordinate=纬度,经度,但在中国大陆同样是 GCJ-02 偏移坐标,所以和高德一样由 worker 做 GCJ-02→WGS84 换算后返回;境外坐标会自动跳过换算(out_of_china 判断)原样返回。除了统一坐标系,走同一接口也方便统一处理短链、文本夹链接、名称解码等。隐私: /api/parse 是纯转发解析——收到链接 → 跟跳转 → 解析坐标 → 返回 JSON,全程不写任何存储、不记日志、不缓存,处理完即丢(wrangler.jsonc 里已显式关闭 observability)。跟跳转时只接受 http/https,单次请求 8 秒超时、只读响应正文前 512 KB。
不放心可自行部署: worker 源码完全开源,可自己部署一份替换上面的地址:
worker/src/index.jsworker/src/parse.jsworker/src/page.js、worker/src/gcj-browser.jswloc-spoofer.wloc.workers.dev 换成你自己的 worker 域名即可。解析逻辑带一套不联网的回归测试,改动后跑一下:
cd worker && npm install && npm test
坐标系说明: 页面内部一律以 WGS84 为准。底图切到「高德」时,瓦片画的是 GCJ-02 地物,与 Leaflet 的 WGS84 像素映射差着一个偏移量(深圳一带约 600 米),页面会在 选点/落点时自动双向换算,所以在任意底图上点选得到的都是同一个 WGS84 坐标。
各家地图的坐标系不同,换算按「来源 × 地区」分派:
| 来源 | 中国大陆 | 港澳台 |
|---|---|---|
| 苹果地图 / Google | GCJ-02,需换算 | WGS84,不换算 |
| 高德 / 百度 | GCJ-02 / BD-09,需换算 | 同左,仍需换算 |
港澳台建议优先用苹果或高德的链接。 百度在港澳台的分享短链,坐标要靠网页脚本
带反爬令牌去查,服务端取不到;变通办法是在浏览器打开该链接,等地址栏变成
map.baidu.com/poi/名称/@数字,数字,19z 之后复制整条地址再粘贴——但百度的针脚位置
与苹果/高德常有几十到两百米的出入(大陆约 5 米,港澳台可达 240 米),精确定位时
不建议用它。
支持 Apple Maps / Google Maps / 高德 / 百度 / 坐标文本 链接解析。
iOS 26/27 及更高版本注意: Apple 从 iOS 26 开始大幅强化了
locationd的定位缓存机制,系统会将之前获取的真实定位结果缓存在内存中并长时间复用。这意味着安装模块或切换目标坐标后,即使脚本已成功修改了 WLOC 响应(日志显示"已修改"),系统仍可能继续使用缓存中的旧坐标,导致定位看起来没有变化。解决方法:重启设备。 重启会清空
locationd的内存缓存,系统重新发起 WLOC 请求时会拿到修改后的坐标。飞行模式开关、关闭定位服务等方式在 iOS 26+ 上无法清除此缓存,必须重启。iOS 15~18 通常不需要重启即可生效。
高版本系统推荐操作流程(成功率最高):
方法一:
方法二:
选点页面 → fetch gs-loc.apple.com/wloc-settings/save?lon=x&lat=y
→ 代理模块拦截 → wloc-settings.js 写入 $persistentStore
→ 下次 WLOC 触发 → wloc.js 读取坐标 → patch protobuf 响应
模块包含两条规则:
wloc.js — 拦截 /clls/wloc 响应,解析 protobuf 并替换坐标wloc-settings.js — 拦截 /wloc-settings/save 请求,写入持久化存储| 参数 | 说明 | 默认值 |
|---|---|---|
| longitude | 目标经度(在线选点优先) | null (透传) |
| latitude | 目标纬度(在线选点优先) | null (透传) |
| accuracy | 精度(米) | 25 |
| randomRadius | 扰动半径(米),每次定位在目标点周围随机偏移,0=关闭 | 0 |
| logLevel | 日志级别 | info |
优先级: 在线选点储存 > 模块参数 > 默认值
扰动半径说明: 启用后每次定位响应会在目标坐标周围指定米数内随机偏移,避免每次定位结果完全相同。Surge/Loon/Stash/Shadowrocket 可在模块参数中设置;QX 用户可通过选点页面设置。默认 0(关闭),不影响现有用户。
方法一:关闭或删除模块(推荐)
关闭模块后脚本不再拦截 WLOC 请求,系统自动恢复真实定位。iOS 26+ 需要重启设备清除定位缓存。
方法二:清除持久化数据(透传模式)
清除已保存的坐标后,脚本进入透传模式——不修改 WLOC 响应,直接放行原始数据,系统自动恢复真实 GPS 定位。
透传模式触发条件: 持久化数据为空(null)且模块参数为默认值(113.94114, 22.544577)时,脚本判定用户未自定义坐标,自动跳过修改。模块默认参数无需更改,仅清除持久化数据即可触发透传。
在代理工具中删除持久化数据,字段名为 wloc_settings:
$persistentStore.write(null, "wloc_settings")$prefs.removeValueForKey("wloc_settings")$persistentStore.write(null, "wloc_settings")清除后重启设备即可恢复真实定位。无需关闭模块,脚本会自动检测到无自定义坐标并跳过修改。
注意: 如果用户在模块参数中手动修改了经纬度(非默认 113.94114, 22.544577),即使清除持久化数据,脚本仍会使用模块参数中的坐标进行修改。只有保持默认参数不变时,清除持久化数据才会进入透传模式。
在线选点页面支持收藏多个位置,方便来回切换:
数据存储说明:
localStorage(仅用于选点页面的 UI 便捷操作)$persistentStore(脚本运行时实际读取的数据)两者独立存储。收藏列表是浏览器端的辅助数据,清除浏览器缓存或换浏览器后需重新收藏,但不影响已储存到设备的生效坐标。
公共选点页面有请求上限,建议部署自己的实例:
https://wloc-spoofer.wloc.workers.dev/https://wloc-pages.pages.dev/一键部署(Workers):
一键部署仅支持 Workers 模式,点击按钮后按提示授权即可完成部署。
手动部署(Workers):
# 1. 克隆仓库
git clone https://github.com/Yu9191/wloc.git
cd wloc/worker
# 2. 安装依赖
npm install
# 3. 登录 Cloudflare(首次需要)
npx wrangler login
# 4. 部署
npm run deploy
部署成功后会得到你自己的 Worker 地址(如 https://wloc-spoofer.<你的子域名>.workers.dev),用这个地址选点即可。
免费账户每天 10 万次请求,个人使用完全够用。
Pages 部署不支持一键按钮,需要手动执行:
git clone https://github.com/Yu9191/wloc.git
cd wloc/worker
npm install
npm run pages:deploy
必须走
npm run pages:deploy(它带-c wrangler.pages.jsonc)。直接跑wrangler pages deploy dist会丢掉配置里的 compatibility 设定。
部署时会提示设置 production branch,输入 main 即可。部署成功后得到 https://<项目名>.pages.dev 地址。
Pages 和 Workers 功能完全一致,按需选择即可。
gs-loc.apple.com 和 gs-loc-cn.apple.com本项目采用 AGPL-3.0 许可证。未经授权,禁止将本项目代码用于商业产品或上架应用商店。
JavaScript
100.0%