v147 · Security · Private Network Access
Compatibility Lab
Detects Private Network Access enforcement context. Classifies the current page origin (public / private / loopback), shows which fetch targets require PNA preflights, and provides the server-side Access-Control-Allow-Private-Network header pattern with the OPTIONS preflight handler.
API probes
Network address classification
| Range | Classification | Fetch from public origin (Chrome 147) |
|---|---|---|
| 127.0.0.0/8 (localhost) | Private (loopback) | BLOCKED — requires PNA preflight |
| 10.0.0.0/8 | Private (RFC 1918) | BLOCKED — requires PNA preflight |
| 172.16.0.0/12 | Private (RFC 1918) | BLOCKED — requires PNA preflight |
| 192.168.0.0/16 | Private (RFC 1918) | BLOCKED — requires PNA preflight |
| 169.254.0.0/16 | Link-local | BLOCKED — requires PNA preflight |
| Public IPs | Public | ALLOWED — no PNA header needed |
Live context probe
Current page origin classification
Click "Run probe" to inspect network context…
Server-side fix pattern
/* Private Network Access preflight handling (server-side) */
/* Browser sends OPTIONS preflight with:
Access-Control-Request-Private-Network: true
when a public page fetches a private IP. */
/* Node.js / Express — handle PNA preflight */
app.options('/api/data', (req, res) => {
const wantsPNA = req.headers['access-control-request-private-network'];
res.set({
'Access-Control-Allow-Origin': req.headers.origin || '*',
'Access-Control-Allow-Methods': 'GET, POST',
'Access-Control-Allow-Headers': 'Content-Type',
...(wantsPNA ? { 'Access-Control-Allow-Private-Network': 'true' } : {}),
});
res.status(204).end();
});
/* Client (public origin) — no special headers needed client-side */
async function fetchPrivateDevice(url) {
try {
return await fetch(url).then(r => r.json());
} catch (e) {
// PNA preflight blocked → server needs Access-Control-Allow-Private-Network header
throw e;
}
}
/* Detect current context */
function getNetworkContext() {
const h = location.hostname;
if (h === 'localhost' || h === '127.0.0.1' || h === '::1') return 'loopback';
if (/^192\.168\./.test(h) || /^10\./.test(h)) return 'private';
if (/^172\.(1[6-9]|2\d|3[01])\./.test(h)) return 'private';
if (/^169\.254\./.test(h)) return 'link-local';
return 'public'; // PNA enforcement active
}
references
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗