Skip to content

Instantly share code, notes, and snippets.

@bellbind
Last active May 27, 2022 15:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bellbind/72e3cdb18adefdcd0306585ce8471f5c to your computer and use it in GitHub Desktop.
Save bellbind/72e3cdb18adefdcd0306585ce8471f5c to your computer and use it in GitHub Desktop.
[browser][deno] Example registration page and its server of API: navigator.registerProtocolHandler()
#!/usr/bin/env -S deno run --allow-net
// Example registration page and its server of API: navigator.registerProtocolHandler()
import {serve} from "https://deno.land/std/http/server.ts";
// A pattern of protocol scheme name is limited with prefix "web+" as web+lowerletters ,
// or whitelisted names in https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler
const protocol = "web+local";
// navigator.registerProtocolHandler() should be called in user inputs (e.g. button click)
// - forwarded url must be same origin of the location.href
const regHtml = `<!doctype html>
<html>
<head>
<link rel="icon" href="data:image/x-icon;," />
<script type="module">
document.getElementById("reg").addEventListener("click", () => {
navigator.registerProtocolHandler(
"${protocol}", location.href + "%s", "protocol handler example");
});
</script>
</head>
<body>
<button id="reg">register protocol: ${protocol}</button> then
<ul>
<li>GET <a href="${protocol}:foo">${protocol}:link</a></li>
<li><form action="${protocol}:form" method="POST"><input type="submit" value="POST ${protocol}:form" /></form></li>
<li><button onclick='(async () => {
alert(await (await fetch("${protocol}:fetch")).text());
})().catch(err => alert(err.message))'>fetch ${protocol}:fetch (but error)</button></li>
<li>Or type "${protocol}:bar" into URL bar directly</li>
</ul>
</body>
</html>`;
// NOTE: custom procotol urls are not available with fetch()
await serve(req => {
console.log(req.method, req.url);
const url = new URL(req.url);
if (url.pathname === "/") {
return new Response(regHtml, {headers: {"content-type": "text/html;charset=utf-8"}});
}
// embeded custom protocol can be decoded with decodeURIComponent()
const decoded = decodeURIComponent(url.pathname.slice(1));
if (decoded.startsWith(`${protocol}:`)) {
const value = decoded.slice(protocol.length + 1);
return new Response(value);
}
return new Response("Not Found", {status: 404});
}, {port: 3000});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment