4

残念ながら、正しい解決策が見つかりませんでした。windows-1251 (cp1251) でエンコードされた URL スライスをデコードする必要があります。

これらのメソッドがあることは知っていますが、 decodeURI()decodeURIComponent()がありますが、(私が理解しているように) UTF-8 でのみ機能します。私が見つけた解決策は、非推奨のメソッド escape() および unescape() を使用しています。

たとえば、次のようなシーケンスがあります。

%EF%F0%EE%E3%F0%E0%EC%EC%E8%F0%EE%E2%E0%ED%E8%E5 (ジャンク)

メソッド decodeURI() および decodeURIComponent() は例外を引き起こします。

助けてくれてありがとう。

4

2 に答える 2

3

私が見る限り、ブラウザには従来の文字セットを使用したパーセント エンコーディング スキームの組み込みサポートはありません。次のことを行う必要があります。

  1. win-1251 オクテットを表す % エスケープを見つけます。
  2. win-1251 オクテットを対応する文字 (JS String)にデコードします。

以下は、その方法の 1 つです。#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"))

于 2017-01-03T20:09:26.167 に答える