1

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

我已经查找了这个问题,但找不到任何明智的解决方案。Node.js 有一个名为punycode. 现在,如果 myreq.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();
});

很感谢任何形式的帮助。谢谢!

4

1 回答 1

0

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

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

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

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

于 2016-03-20T10:48:57.050 回答