我可以向 Node HTTP 服务器注册自定义 URL Scheme/Protocol 吗?

Can I register a custom URL Scheme/Protocol with a Node HTTP Server?

我希望能够使用 Node HTTP API 处理自定义 URL 方案。我想在网页内写这样的链接:app://foo/bar。我想让节点 HTTP 请求处理程序接收这种 URL.

当我在我的 URL 中尝试这种自定义协议时,看起来 Chrome 没有发送请求,因为它格式错误。所以我在 Node.

中的 HTTP 服务器什么也得不到

是否可以将您的 HTTP 服务器绑定到自定义 URL 方案或协议,例如 app://foo/bar

只有某些协议,例如 http://https:// 会被发送到您的 nodejs http 服务器。这就是问题所在。您的 node.js 服务器是一个 http 服务器。 chrome 浏览器将仅使用它知道属于 http 服务器的 http 协议向它发送 URLs。

必须先在浏览器中使用浏览器插件处理自定义协议,然后再决定如何处理它。


也许您想做的是自定义 HTTP URL 例如:

http://yourserver.com/foo/bar

然后,您的 node.js http 服务器将获得请求的 /foo/bar 部分,您可以为此编写自定义处理程序。


回顾一下,URL 的第一部分 :// 之前的部分是协议。这告诉浏览器这个 URL 应该与什么协议一起使用。如果没有浏览器插件,浏览器仅支持一些内置协议,例如 httphttpswswssmailto和其他一些。

http 服务器只能响应 http 协议,因此它只能与希望使用 http 协议且浏览器知道使用 http 协议的 URL 一起使用。因此,浏览器不知道的您自己的协议不是浏览器知道如何处理的。需要一个浏览器插件来告诉浏览器如何处理自定义 URL.

When I try this kind of url, it almost looks like Chrome is batting it down before it can get to my HTTP server in Node.

是的,它不是浏览器内置的可识别协议,因此浏览器不知道如何处理它或如何使用该协议。

Is it possible to bind your HTTP server to a custom URL Scheme like this?

仅使用注册并实现对自定义 URL 协议支持的浏览器加载项。

根据其他答案的评论线程,我想我明白你想做什么。

我听说您想关闭 localhost 提供一些文件,但根本不会污染现有网络服务器的命名空间。

我有几个奇怪的替代解决方案:

  1. 只需选择用户不太可能使用的名称空间即可。您可以以下划线或美元符号开头吗?或者你可以只是一个非常随机的数字。
  2. 您可以提供您的文件,但前提是 URI 参数存在且字符串非常随机。例如,PHP 这样做是为了服务 PHP 徽标。
  3. 如果不创建浏览器add-ons,您无法真正更改方案,但是您确实可以控制 TCP 端口。您可以在第二个端口上启动第二个网络服务器。
  4. 您可以使用第二个域。只需注册一个域并将 A 记录指向 127.0.0.1。现在,您在本地主机上的网络服务器 运行 可以检查 Host: header 并在与您的特殊主机名匹配时提供您的文件。

我为此制作了一个 npm 模块。

link :https://www.npmjs.com/package/protocol-registry

所以要在 nodejs 中执行此操作,您只需要 运行 下面的代码:

首先安装它

npm i protocol-registry

然后使用下面的代码注册您的条目文件。

const path = require('path');

const ProtocolRegistry = require('protocol-registry');

console.log('Registering...');
// Registers the Protocol
ProtocolRegistry.register({
    protocol: 'testproto', // sets protocol for your command , testproto://**
    command: `node ${path.join(__dirname, './index.js')} $_URL_`, // $_URL_ will the replaces by the url used to initiate it
    override: true, // Use this with caution as it will destroy all previous Registrations on this protocol
    terminal: true, // Use this to run your command inside a terminal
    script: false
}).then(async () => {
    console.log('Successfully registered');
});

然后假设有人打开testproto://test 然后将启动一个新终端执行:

node yourapp/index.js testproto://test