跳转到内容

能力中的概念

ERR_LOCAL_NETWORK_PERMISSION_MISSING 排查

发布于

有限可用不支持的浏览器: Firefox (Desktop)、Firefox (Android)、Safari (macOS)、Safari (iOS)WICG 草案

公共页面请求本地或 loopback 目标时,如果 Chrome 无法通过权限和地址空间检查,就会产生 Local Network Access 错误。页面 JavaScript 通常只收到被拒绝的 fetch() Promise,DevTools 才可能显示更具体的 Chromium 网络错误。

Chrome 142 上线 Local Network Access 权限提示。Chrome 公告说明首个版本覆盖 fetch()、子资源加载和子框架导航;规范定义安全上下文、权限、Permissions Policy 和目标地址空间检查。BCD 对 Request.targetAddressSpace 的支持记录包括 Chrome 142 及镜像的 Chromium 派生浏览器;完整支持范围见兼容性数据。BCD 未记录 Firefox 或 Safari 支持。

在 Chrome 首个里程碑中,从公共地址空间发往 local 或 loopback 目标的请求属于本地网络请求。规范要求客户端处于安全上下文,存在关联文档,Permissions Policy 允许访问,并且页面取得 local-network 或 loopback-network 授权。如果权限状态为 prompt,用户代理会询问用户,只有同意后才继续。

Fetch API 不会把 Chromium 内部网络错误码作为结构化 JavaScript 值暴露出来。因此,fetch() 被拒绝只是诊断起点,不能证明用户拒绝了权限。还要查看 DevTools、请求 URL、页面安全上下文、响应的 CORS 标头,以及目标设备是否响应。

信号 来源给出的含义 下一项检查
net::ERR_LOCAL_NETWORK_PERMISSION_MISSING Chromium 因缺少本地网络权限而阻止请求 请用户检查该站点的本地网络权限
net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS Chromium 在 Local Network Access 检查中阻止连接,并把这个错误码留给 CORS 错误路径 比较声明与解析后的地址空间,并检查策略
fetch() 在 JavaScript 中抛出 TypeError Fetch 以网络错误结束 配合 DevTools 和服务端日志,区分权限、CORS、混合内容、DNS、拒绝连接和超时
没有出现权限提示 请求可能在提示前失败,或文档没有提示资格 检查安全上下文、关联文档和 Permissions Policy

targetAddressSpace: "local" 或 "loopback" 用来声明目标。规范允许这项声明绕过对应的混合内容升级步骤,连接后再比较解析地址与声明;两者不匹配时返回网络错误。它既不会授予权限,也不会替设备补上 CORS 响应标头,只是一项声明和约束。

worker 需要额外处理。当前规范在请求没有关联 Document 时返回网络错误,旁注明确指出 Service Worker 会受影响。Chromium issue 404887282 跟踪 Service Worker 的 Local Network Access 行为。把网络任务移入 worker 前,应先从文档流程取得授权,并保留文档侧回退。

失败边界 应调整的内容
权限被拒绝或缺失 说明连接用途,让用户修改站点权限后重试
Permissions Policy 阻止 iframe 向目标 frame 委派 local-network、loopback-network,或 Chromium 的合并别名
地址空间声明与 DNS 结果不符 修正 targetAddressSpace 或主机名;不要为了访问公共目标而放宽声明
设备没有允许 CORS 配置设备 HTTP 响应,允许发起请求的源
设备离线或拒绝连接 提供设备设置和连接检查
浏览器没有 targetAddressSpace 使用 HTTPS 端点或浏览器支持的设备能力,不要假定 Chrome 路径存在

下面两个示例都从安全文档开始。它们返回应用状态,不会声称一个 JavaScript TypeError 就能识别具体网络原因。

特性检测让不支持的路径不使用 Chrome 专有请求成员。catch 分支记录错误名称,并告诉界面仍需进一步诊断。

<label>
设备状态 URL
<input id="device-url" type="url" value="http://192.168.1.1/status">
</label>
<button id="read-device" type="button">读取状态</button>
<output id="read-result" aria-live="polite"></output>
<script>
async function readDeviceStatus(url = 'http://192.168.1.1/status') {
if (!window.isSecureContext) {
return { ok: false, reason: 'secure-context-required' };
}
if (!('targetAddressSpace' in Request.prototype)) {
return { ok: false, reason: 'address-space-option-unsupported' };
}
try {
const response = await fetch(url, {
targetAddressSpace: 'local',
});
if (!response.ok) return { ok: false, reason: `http-${response.status}` };
return { ok: true, data: await response.json() };
} catch (error) {
return { ok: false, reason: 'network-error', errorName: error.name };
}
}
const readButton = document.querySelector('#read-device');
const deviceUrl = document.querySelector('#device-url');
const readResult = document.querySelector('#read-result');
if (readButton && deviceUrl && readResult) {
readButton.addEventListener('click', async () => {
readButton.disabled = true;
const result = await readDeviceStatus(deviceUrl.value);
readResult.textContent = JSON.stringify(result);
readButton.disabled = false;
});
}
</script>

界面现在可以把配置问题和 HTTP 响应分开。若支持人员需要区分权限与地址空间检查,仍需从 DevTools 或受管遥测中取得 Chromium 网络错误码。

按当前规范旁注,Service Worker 没有可靠的提示界面。下面的消息处理器把控制权交还文档,用户点击后由文档发出请求,Chrome 因而有机会显示权限 UI。

<button id="retry-device" type="button" hidden>重试设备连接</button>
<output id="device-result" aria-live="polite"></output>
<script>
const retryButton = document.querySelector('#retry-device');
const deviceResult = document.querySelector('#device-result');
function renderDeviceResult(result) {
if (!deviceResult) return;
deviceResult.textContent = result.ok
? JSON.stringify(result.data)
: `设备请求已停止:${result.reason}`;
}
if (retryButton) {
retryButton.addEventListener('click', async () => {
if (retryButton.disabled) return;
retryButton.disabled = true;
const result = await readDeviceStatus();
renderDeviceResult(result);
retryButton.hidden = result.ok;
retryButton.disabled = false;
});
}
navigator.serviceWorker.addEventListener('message', (event) => {
if (event.data?.type !== 'local-network-retry-required') return;
if (!retryButton) return;
retryButton.hidden = false;
});
async function requestFromWorker() {
const controller = navigator.serviceWorker.controller;
if (!controller) return readDeviceStatus();
controller.postMessage({ type: 'read-local-device' });
return { ok: false, reason: 'delegated-to-worker' };
}
requestFromWorker().then(renderDeviceResult);
</script>

worker 的请求被拒绝后,应发送 local-network-retry-required。文档不能保证重试成功;CORS、地址不匹配或设备不可达仍会产生网络错误。Web Bluetooth 兼容性数据展示了另一条需要权限的设备连接路径,适用于提供蓝牙而非 HTTP 服务的设备。

规范

规范状态
本地网络访问(Request.targetAddressSpace)WICG 草案
  • 图例
  • 支持
  • 部分支持
  • 需开启标志
  • 不支持
  • 未知
浏览器 / 平台支持版本置信度来源备注
Chrome (Desktop)#支持142高来源—
Chrome (Android)#支持142高来源1
Edge (Desktop)#支持142高来源2
Firefox (Desktop)#不支持—高来源3
Firefox (Android)#不支持—高来源45
Safari (macOS)#不支持—高来源6
Safari (iOS)#不支持—高来源78
Samsung Internet#支持30.0高来源9
WebView (Android)#不支持—高来源10
  1. 由 browser-compat-data 镜像自 Chrome 的数据推导。
  2. 由 browser-compat-data 镜像自 Chrome 的数据推导。
  3. browser-compat-data 未记录 Firefox 的支持。
  4. browser-compat-data 未记录 Firefox for Android 的支持。
  5. 由 browser-compat-data 镜像自 Firefox 的数据推导。
  6. browser-compat-data 未记录 Safari 的支持。
  7. browser-compat-data 未记录 iOS 版 Safari 的支持。
  8. 由 browser-compat-data 镜像自 Safari 的数据推导。
  9. 由 browser-compat-data 镜像自 Chrome Android 的数据推导。
  10. browser-compat-data 未记录 WebView Android 的支持。

源数据: /compatibility/local-network-access.json · 全球使用占比: 75 % (StatCounter 2026-09, CC BY-SA 4.0)

来源: 规范 · MDN · 最近核验 2026-10-28 · 置信度: 高 (由来源计算)