JS browser library for trying to determine whether a connection failed due to denied Local Network Access permissions.
import {detectLna, LnaError} from "qz-lna";
try {
await detectLna("http://127.0.0.1:8000", fetch)
} catch (e) {
if (e instanceof LnaError && e.denied) {
// Teach the user a lesson about clicking "no" on popups
} else {
// Failed for another or for an unknown reason, display error message
throw e;
}
}- Browser implementations vary and are changing rapidly. While we make our best effort to reflect the current state of the web platform, there may always be inaccuracies. Using the latest version of this library may be essential to ensure future functionality.
- Public domain names in origin or target address are not resolved, but assumed to be in
public. If you have a domainexample.comthat resolves to a local IP address, you should override this behavior usingoptions.defaultAddressSpaceoroptions.override. - Browser settings or policies (such as Chrome's LocalNetworkAccessAllowedForUrls) may change whether permissions are required for a given request, with no way for the library to know about it.
- We can't detect when a permission prompt is dismissed (such as by pressing Esc) rather than explicitly allowed or denied.
We provide three compiled variants of the library:
dist/lna.bundle[.min].js: IIFE bundle for direct use in browsers, transpiled with bundled dependencies and polyfills for older browsers. API is available as global variablelna.dist/lna.mjs: ECMAScript module for use with bundlers.dist/lna.cjs: CommonJS module for use with bundlers.
To use:
-
If you're using a bundler for your project, you can install the package from npm:
npm install qz-lna
-
If you're using a browser environment without a bundler, you can include the script directly from a CDN, e.g.
<script src="https://cdn.jsdelivr.net/npm/qz-lna@0.1/dist/lna.bundle.min.js"></script>
The library will be available as global variable
lna. -
Alternatively, you can build the library from source:
yarn install yarn build
The API consists of a single function detectLna:
declare async function detectLna<R>(
url: string | URL,
callback: (url: string | URL) => R,
options?: LnaOptions
): RThis calls and awaits callback with the given url.
If the callback throws an error that indicates connection failure, detectLna throws an LnaError instance with the following properties:
denied: boolean | undefinedindicates whether permission for this request was denied, orundefinedif unknownpermission: PermissionStatus | null | undefinedthe applicable permission query result.nullif no permission is required,undefinedif unknown
If the target or origin address space is known to the caller, it's recommended that the (inherently
inaccurate) automatic detection be bypassed using the options parameter:
type LnaOptions = {
override?: {
targetAddressSpace?: AddressSpace,
originAddressSpace?: AddressSpace,
},
defaultAddressSpace?: AddressSpace, // Address space to assume for public domains
isWebSocket?: boolean,
isConnectionError?: (error: unknown) => boolean,
}where AddressSpace is one of "local", "loopback" or "public".
You can also globally configure by modifying the exported defaultOptions.