0

我有一个使用以下cors中间件配置运行的 Express 服务器:

app.use(
  cors({
    origin: [
      /^http:\/\/localhost:\d+/,
      /^https:\/\/щоденниквражень\.укр/,
      /^https:\/\/xn--80adfecflqzagb7a3ioc\.xn--j1amh/,
    ],
  }),
);

xn--80adfecflqzagb7a3ioc.xn--j1amh是 Punycode 的表示щоденниквражень.укр

我已从https://щоденниквражень.укр托管的页面向https://api.щоденниквражень.укр提出请求。大多数浏览器在Origin标头中发送 Punycode 表示,这可以按预期工作。

但是 IE11 发送原始的https://щоденниквражень.укр. 它应该与列表中的第二个正则表达式匹配,但在服务器端,我从req.headers.origin: 获得以下标头值
Origin: https://Ñ Ð¾Ð´ÐµÐ½Ð½Ð¸ÐºÐ²ÑаженÑ.ÑкÑ
,显然,它无法匹配任何正则表达式(某些字符可能显示不正确,但你明白了 -字符集是错误的)。

有可能解决这个问题吗?我想我可能应该设置编码 - 但我不知道在哪里做以及选择哪一个。任何帮助表示赞赏!

4

1 回答 1

1

首先,问题不在于字符集。由于某种原因,Node.js 无法处理西里尔字符,并且它们被错误地解码。我没有找到解决这个问题的正确方法,所以如果有人在这里发布它,我会非常高兴:)

但我有一个解决方法。我找到了网站https://dom.hastin.gs/files/utf8/#可以修复我的Origin价值并实现它https://щоденниквражень.укр。我在 DevTools 中查看了它的源代码,它使用了一些库文件unicode.min.js(奇怪的是,我还没有找到它的 GitHub 存储库或源代码)。这是该库的链接:https ://dom.hastin.gs/files/utf8/unicode.min.js (以防万一它坏了,我在 Google Drive 上做了一个备份:https://drive.google。 com/file/d/1erDSjdEQL5tOAvodeaVdHfnx7CvKApmn/view?usp=sharing )

现在我可以像这样在我的代码中使用库来转换Origin字符串:

// Load Cyrillic characters
// Check out `Unicode.blocks` for a list of available blocks,
// then call `Unicode.load(<START>, <END>)`
Unicode.load(1024, 1279);

// Fix the string
Unicode.fix('https://щоденниквражень.укр'); // Returns 'https://щоденниквражень.укр'

我知道这不是正确的解决方案,但它可以完成工作,我希望它对任何偶然发现这个问题的人有所帮助。事实上,这是一个更普遍的问题:在 Node.js 中处理 HTTP 标头中的非 ASCII 字符 - 与 CORS 不严格相关。

更新:我已经通过美化器运行了库代码并研究了它的代码。作者做得非常好,但在我看来,特别是为了解码 HTTP 标头的目的,这有点矫枉过正。有很多机会可以提高性能和降低复杂性,所以我建议每个想要使用这个库的人查看代码并重构它以更好地适应你的特定用例——这就是我所做的。我对结果很满意,我认为它可以被宣布为解决问题的好方法

于 2020-10-17T13:31:45.153 回答