在单个模块中覆盖node.js的querystring.escape函数

7
我想在一个对象上使用querystring.stringify。字符串的要求略有不同,星号、斜杠和撇号都需要转义。querystring不会转义这些字符(通常不需要),但文档指出querystring.escape是公开的,以便我们可以用自己的函数覆盖它。以下内容适用于我:
querystring.escape = function(str) {
    str = encodeURIComponent(str)
        .replace(/\*/g, '%2A')
        .replace(/\(/g, '%28')
        .replace(/\)/g, '%29')
        .replace(/'/g, '%27');
    return str;
};

我的唯一担忧是,如果我理解正确的话,这可能会改变其他模块的行为,这些模块将来也可能需要使用querystring(带有其正常转义函数)。node.js文档表示,模块只加载一次,并返回原始实例以供后续的require调用。是否有一种方法可以强制使此特定实例的querystring成为唯一的?
显然,我可以编写一个包装器,在传统的querystring.stringify调用之后执行替换,但我很好奇,因为对我来说,标准节点模块似乎真的有一个“全局”设置,除非实际上有一种方式要求unique instance。

感谢您提供的这个链接:https://github.com/flatiron/cradle/pull/313/files#diff-73b7aef1765d18b91942243d634fe790R10 - ceremcem
1个回答

6

有没有办法强制使此查询字符串实例唯一?

实际上没有。Node的模块缓存是基于进程且基于模块的文件路径

更改不会跨越子进程群集。因此,您可以通过其中一个隔离自己的脚本来使用自己的querystring

但是,在同一进程中,Node没有官方方法来绕过此功能,以仅为单个模块检索唯一实例。


这可能会改变其他可能在未来也需要querystring(带有其正常转义函数)的模块的行为。

好的,如果URL编码的值具有附加编码字符,则仍然有效。只是通常它们不需要。

我想,可能会影响对编码值有期望的模块。但是,那通常是一个奇怪的选择(例外是您自己的querystring.escape的单元测试)。因此,只要可以正确解码,就应该没问题。

querystring.escape = function (str) { /* ... */ }; // your function here

var sample = "a(b*c)'d";

var encoded = querystring.escape(sample);
console.log(encoded);             // a%28b%2ac%29'd

var decoded = querystring.unescape(encoded);
console.log(decoded);             // a(b*c)'d
console.log(decoded === sample);  // true

同时,覆盖querystring.escapequerystring.unescape的能力是有意设计的:

querystring.stringify使用的转义函数提供了覆盖的可能性,以便在必要时进行覆盖。


谢谢。很高兴知道重新定义它以转义更多字符可能并不重要,但我真正好奇的核心问题——无论当前需求如何——是node是否提供了一种机制来重新定义它,而不会影响其他也需要('querystring')的模块,例如通过强制使用querystring的唯一实例。我更新了标题以使其更清晰。 - Semicolon
@分号 不完全是这样。作为核心模块querystring每个node进程只存在一次。设置它不会跨越子进程集群,但除此之外,不可能仅更改单个模块。 - Jonathan Lonowski
啊,好的,我相信你在节点方面很专业。如果你想把这个信息加入到答案中,我会标记它为已接受。 - Semicolon
我遇到了同样的问题,并向Node提交了一个错误报告:https://github.com/nodejs/node-v0.x-archive/issues/8672 - Daniel Gasienica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接