使用 Node.js 中的 Unicode 字符解码 HTTP headers
Decoding HTTP headers with Unicode characters in Node.js
我有一个 Express 服务器 运行 以下 cors
中间件配置:
app.use(
cors({
origin: [
/^http:\/\/localhost:\d+/,
/^https:\/\/щоденниквражень\.укр/,
/^https:\/\/xn--80adfecflqzagb7a3ioc\.xn--j1amh/,
],
}),
);
(xn--80adfecflqzagb7a3ioc.xn--j1amh
是 щоденниквражень.укр
的 Punycode 表示)
我已向 https://api.щоденниквражень.укр from a page hosted at https://щоденниквражень.укр 提出请求。大多数浏览器在 Origin
header 中发送 Punycode 表示,这按预期工作。
但是 IE11 发送原始 https://щоденниквражень.укр
。它应该匹配列表中的第二个正则表达式,但在服务器端我从 req.headers.origin
得到以下 header 值:
Origin: https://Ñ Ð¾Ð´ÐµÐ½Ð½Ð¸ÐºÐ²ÑаженÑ.ÑкÑ
显然,它无法匹配任何正则表达式(某些字符可能显示不正确,但您明白了 - 字符集错误)。
这个问题可以解决吗?我想我应该设置编码 - 但我不知道在哪里做以及选择哪个。感谢您的帮助!
首先,问题不在于字符集。出于某种原因 Node.js 无法处理西里尔字符并且它们被错误地解码。我没有找到解决这个问题的正确方法,所以如果有人在这里发帖我会非常高兴:)
但我有一个解决方法。我找到了网站 https://dom.hastin.gs/files/utf8/# which can fix my Origin
value and make it https://щоденниквражень.укр
. I checked out its source code in DevTools and it uses some library file unicode.min.js
(strangely, I haven't found its GitHub repo or source code). Here is a link to that library: https://dom.hastin.gs/files/utf8/unicode.min.js (in case it ever breaks, I made a backup on 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://щоденниквражень.укр'
我知道这不是正确的解决方案,但它可以解决问题,我希望它对遇到此问题的任何人有所帮助。事实上,这是一个更普遍的问题:handling non-ASCII characters in HTTP headers in Node.js - not strictly related to CORS.
更新: 我通过美化器运行 库代码并研究了它的代码。作者确实做得很好,但是,在我看来,专门针对 HTTP headers 解码的目的有点大材小用。有很多提高性能和降低复杂性的机会,所以我建议所有想使用这个库的人看一下代码并重构它以更好地适应您的特定用例——我就是这样做的。我对结果很满意,我认为它可以被宣布为解决问题的好方法
我有一个 Express 服务器 运行 以下 cors
中间件配置:
app.use(
cors({
origin: [
/^http:\/\/localhost:\d+/,
/^https:\/\/щоденниквражень\.укр/,
/^https:\/\/xn--80adfecflqzagb7a3ioc\.xn--j1amh/,
],
}),
);
(xn--80adfecflqzagb7a3ioc.xn--j1amh
是 щоденниквражень.укр
的 Punycode 表示)
我已向 https://api.щоденниквражень.укр from a page hosted at https://щоденниквражень.укр 提出请求。大多数浏览器在 Origin
header 中发送 Punycode 表示,这按预期工作。
但是 IE11 发送原始 https://щоденниквражень.укр
。它应该匹配列表中的第二个正则表达式,但在服务器端我从 req.headers.origin
得到以下 header 值:
Origin: https://Ñ Ð¾Ð´ÐµÐ½Ð½Ð¸ÐºÐ²ÑаженÑ.ÑкÑ
显然,它无法匹配任何正则表达式(某些字符可能显示不正确,但您明白了 - 字符集错误)。
这个问题可以解决吗?我想我应该设置编码 - 但我不知道在哪里做以及选择哪个。感谢您的帮助!
首先,问题不在于字符集。出于某种原因 Node.js 无法处理西里尔字符并且它们被错误地解码。我没有找到解决这个问题的正确方法,所以如果有人在这里发帖我会非常高兴:)
但我有一个解决方法。我找到了网站 https://dom.hastin.gs/files/utf8/# which can fix my Origin
value and make it https://щоденниквражень.укр
. I checked out its source code in DevTools and it uses some library file unicode.min.js
(strangely, I haven't found its GitHub repo or source code). Here is a link to that library: https://dom.hastin.gs/files/utf8/unicode.min.js (in case it ever breaks, I made a backup on 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://щоденниквражень.укр'
我知道这不是正确的解决方案,但它可以解决问题,我希望它对遇到此问题的任何人有所帮助。事实上,这是一个更普遍的问题:handling non-ASCII characters in HTTP headers in Node.js - not strictly related to CORS.
更新: 我通过美化器运行 库代码并研究了它的代码。作者确实做得很好,但是,在我看来,专门针对 HTTP headers 解码的目的有点大材小用。有很多提高性能和降低复杂性的机会,所以我建议所有想使用这个库的人看一下代码并重构它以更好地适应您的特定用例——我就是这样做的。我对结果很满意,我认为它可以被宣布为解决问题的好方法