不幸的是,我遇到了一个问题,我没有找到正确的解决方案:我需要解码使用Windows-1251(cp1251)编码的url-slice。

我知道有这些方法-decodeURI()和decodeURIComponent(),但是它们仅适用于UTF-8(据我所知)。我找到的解决方案使用了不赞成使用的方法escape()和unescape()。

例如,有序列:

%EF%F0%EE%E3%F0%E0%EC%EC%E8%F0%EE%E2%E0%ED%E8%E5(программирование)

方法decodeURI()和decodeURIComponent()将导致异常。

将感谢您的帮助。

最佳答案

据我所知,浏览器中没有对带有旧字符集的百分比编码方案的内置支持。您必须:


找到代表win-1251八位位组的%转义,
将win-1251八位字节解码为相应的字符(JS String


以下是一种方法。对于#1,我假设只有3个字符的大写转义字符需要解码,并且字符串的其余部分已经是ASCII,因此我只使用inputStr.replace(/%([0-9A-Z]{2})/g, replacerFunction )

对于实际的解码,您需要从win-1251八位字节到JS字符的映射。在下面的示例中,我出于娱乐目的使用TextDecoder.decode() API构建映射(以防万一有人在尝试在JS中的不同字符集之间进行转换时找到此答案)。 (注意:目前尚不普遍支持,只有Gecko / Blink支持)。

还有https://github.com/mathiasbynens/windows-1251,我最初想将其用于此答案,但事实证明,手工构建解码图会更容易。



var decodeMap = {};
var win1251 = new TextDecoder("windows-1251");
for (var i = 0x00; i < 0xFF; i++) {
  var hex = (i <= 0x0F ? "0" : "") +      // zero-padded
            i.toString(16).toUpperCase();
  decodeMap[hex] = win1251.decode(Uint8Array.from([i]));
}
// console.log(decodeMap);
// {"10":"\u0010", ... "40":"@","41":"A","42":"B", ... "C0":"А","C1":"Б", ...


// Decodes a windows-1251 encoded string, additionally
// encoded as an ASCII string where each non-ASCII character of the original
// windows-1251 string is encoded as %XY where XY (uppercase!) is a
// hexadecimal representation of that character's code in windows-1251.
function percentEncodedWin1251ToDOMString(str) {
  return str.replace(/%([0-9A-F]{2})/g,
    (match, hex) => decodeMap[hex]);
}

console.log(percentEncodedWin1251ToDOMString("%EF%F0%EE%E3%F0%E0%EC%EC%!%E8%F0%EE%E2%E0%ED%E8%E5a"))

关于javascript - 使用JavaScript解码URL编码的Windows-1251(cp1251)字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41448586/

10-09 16:55