替换 Node.js + Express.js 中的主机名以解码 punycode 域

Replace hostname in Node.js + Express.js to decode punycode domain

我正在西里尔域名上开发网络应用程序。目前,此域托管一个 "parked page",表示该站点正在建设中。如果我在 Chrome 中访问它,我会在地址栏中看到 punycode。不过,Safari 会对其进行解码。出于开发目的,我修改了我的 /etc/hosts 文件,以便能够通过测试西里尔域名访问本地主机。但是,Chrome 和 Safari 都无法解码主机名。

我查过这个问题,但找不到任何合理的解决方案。 Node.js 有一个名为 punycode 的模块。现在,如果我的 req.url 包含西里尔字符,它会被 URIComponent 编码,因此我编写了一个中间件来解码它:

app.use(function(req, res, next) {
    var url = req.url,
        decoded = decodeURIComponent(url);

    if (url !== decoded) req.url = decoded;
    next();
});

它工作正常,我现在可以使用西里尔路由。但是当我尝试将此逻辑应用于主机名时,它不起作用:

app.use(function(req, res, next) {
    var hostname = req.hostname,
        decoded = punycode.toUnicode(hostname);

    if (hostname !== decoded) req.hostname = decoded;
    // I have also tried return res.redirect('https://' + decoded + ':' + ...);
    next();
});

非常感谢任何帮助。谢谢!

好的,经过研究,我发现这几乎是不可能的。主机解析策略严格特定于浏览器,并且(关于 IDN)用于防止危险的网络钓鱼活动。一方面,Safari 将 IDN 从 punycode 解析为 UTF-8 字符串,Chrome,另一方面,则不会。

这些危险的网络钓鱼活动可能来自包含非 ASCII 字符的域。考虑一组 ASCII 字母 "o, e, a" 和 UTF-8 俄语(西里尔字母)字母“о, е, а”。它们看起来几乎相同,因此对于客户来说无法区分。因此,黑客 可能会注册一个看起来像众所周知的域("paypal.com" 使用 ASCII "a","pаypаl.com" 使用 UTF- 8 个西里尔字母 "а").

为了防止此类恶意活动,Chrome 将非 ASCII 字符编码为 punycode("pаypаl.com" 使用 UTF-8 西里尔字母“а”在浏览器地址栏中看起来像 "xn--pypl-53dc.com"警告客户这不是原始网站)。

唉,IDN 似乎不是目前最好的解决方案。