# 本地网络访问：本地请求前的权限提示

> Chrome 的 Local Network Access 如何在公网页面访问用户本地网络设备前弹出权限提示，以及它为何取代了此前静默的仅预检方式。

**一句话:** Local Network Access（本地网络访问）是一个浏览器权限提示，在公网上运行的页面尝试向用户本地网络中的设备（例如路由器、打印机或本地应用服务器）发起请求之前弹出。

## 为什么需要提示，而不只是预检

该规范的前身 Private Network Access 允许本地设备通过返回一个 CORS 预检响应头来“同意”被联网页面访问——整个过程中完全没有用户参与。根据 explainer 的说明，这种仅靠预检的方案需要改造本地网络中的设备，而网站比设备容易更新得多。Local Network Access 用浏览器端的权限提示取代了 PNA 的预检门禁，把改造的负担转移到公网页面一侧，而不是本地设备。根据规范，用户代理（user agent）可以持久化这一权限决定以减少权限疲劳，但授权的具体范围——例如按来源、按设备还是按网络——由各实现自行决定。

## 提示如何被触发

根据 Chrome for Developers 博客，触发提示的是公网页面自身发起的、指向本地网络或回环地址的请求——开发者并不需要先调用另一个 API 来请求该权限：

```js
// 一个从公网源加载的页面，请求用户本地网络中的设备
// （例如某个路由器的状态接口）。
const response = await fetch('http://192.168.1.1/status');
```

Chrome 从 138 版本开始以一个 flag（`chrome://flags/#local-network-access-check`，设为
“Enabled (Blocking)”）提供该能力供开发者预先测试，并在 Chrome 142 版本中默认开启该提示。根据
Chrome 博客，依赖该能力的页面必须运行在安全上下文（HTTPS）中，必须妥善处理提示被拒绝的情况，并可以使用
Permissions Policy 将该权限委派给 iframe。

## 支持情况

根据 Chrome for Developers 博客，Local Network Access 提示在经过从 Chrome 138 开始的选择性测试阶段后，于 Chrome 142 默认上线。该规范在 WICG 中制定，根据 explainer 的说明，部分行为——例如两个本地网络来源之间的跨源请求是否也会被此机制拦截——由各实现者自行决定；explainer 指出，目前 Chromium 只对“从公网源发往本地或回环地址”的请求实施该权限限制，并不对本地网络内部的跨源请求实施同样的限制。

## 运行时检测与降级

没有单独的“该浏览器是否会拦截 Local Network Access”查询接口，但 `Request` 上的
`targetAddressSpace` 属性属于同一规范工作的一部分，它的存在可以作为浏览器 fetch 栈是否理解本地网络地址空间的合理信号。在发起请求前，应结合安全上下文一起检查这一点；而请求失败时应当泛化处理——请求被拒绝或抛出异常，可能意味着浏览器不支持、页面不在安全上下文中、用户拒绝了提示、CORS 失败，也可能只是设备离线；而且在 Local Network Access 上线之前，公网页面本来就能够在不触发任何失败的情况下访问本地地址，因此不应把失败归因于某个具体原因：

```js
function supportsLocalNetworkAddressSpaces() {
  return typeof Request !== 'undefined' && 'targetAddressSpace' in Request.prototype;
}

async function pingLocalDevice(url) {
  if (!window.isSecureContext || !supportsLocalNetworkAddressSpaces()) {
    // 该浏览器未暴露本地网络地址空间相关能力，或页面不在安全上下文中，
    // 因此无法依赖这一机制发起请求。
    return false;
  }
  try {
    const res = await fetch(url);
    return res.ok;
  } catch {
    // 请求因未知原因失败（提示被拒绝、CORS、设备离线或其他原因）：
    // 不要静默重试或猜测具体原因，改为让用户手动检查设备。
    return false;
  }
}
```

## 实践清单

- [ ] 根据 Chrome 博客，发起请求的页面必须运行在安全上下文（HTTPS）中——来自非安全页面的本地网络请求根本不会触发该提示。
- [ ] 把请求被拒绝或不受支持当作正常的预期结果处理：捕获失败并向用户展示手动降级方案，而不是静默重试同一个请求。
- [ ] 不要依赖本地设备旧的 Private Network Access 预检 opt-in 响应头来绕过提示——Local Network Access 已经用浏览器端的权限取代了这种服务端 opt-in 机制，本地设备本身无法控制它。
- [ ] 根据 explainer 的说明，Chromium 目前并未像限制“公网到本地”请求那样限制“本地到本地”的跨源请求——不要假设所有本地网络请求路径都被同等覆盖。
- [ ] 如果要在 iframe 中嵌入依赖本地网络的功能，需要通过 Permissions Policy 显式委派该权限，而不是假设它会被自动继承。

## 下一步

- [Web Locks API](/zh/reference/capabilities/web-locks/)
- [Idle Detection API](/zh/reference/capabilities/idle-detection/)