0

どのエンコーディングが使用されていても、ajax 呼び出しを介して Web サーバーに送信されたときに、一部の種類の文字データが破損するのはなぜかという問題を再検討しています。データが 7 ビット フォーマットにプリコードされている場合でも、出力されるデータと入力されるデータが必ずしも一致するとは限りません。

私はサードパーティの javascript base64 エンコーダーを使用して ajax データを準備していましたが、最初はこれにバグがあると考えていました。しかし、完全な Unicode 互換性を主張するものを含め、他の base64 エンコーダーはまったく同じ問題を示しており、同様の問題に関するフォーラム レポートがいくつかありますが、いずれも完全に解決されたようには見えません。したがって、エンコーダー自体に問題があるとは思いません。

データに特定の上位 ASCII/ANSI コードが含まれている場合、通常、他のプログラムから CKEditor にコピー アンド ペーストされたデータで破損が発生することに気付きました。

さらにいくつかのテストでは、javascript が Web ページから文字データを読み取る方法と、String.fromCharCode() などの内部プログラム メソッドから文字列データを形成する方法との間の何らかの不一致に問題があることを示しているようです。

以下のスニペットでは、テキスト エディターからのカット アンド ペーストによって HTML ドキュメントに挿入された文字 0x9E の処理を​​、16 進コード 0x9E (U+017E - Arial Latin small z with caron, Windows西洋文字セット)。これは、この異常な動作を引き起こすことが確認されているいくつかの文字コードの 1 つです。奇妙なことに、127 文字を超える他のほとんどの文字コードでは、このような問題は発生せず、本来あるべき 2 バイトの Unicode としてレンダリングされます。

<script>
  var pasted_char = 'ž';
  alert("Pasted Character: " + pasted_char + " Resultant Code(s): " + charcodes(pasted_char));

  var charcode = 0x9E;
  var generated_char = String.fromCharCode(charcode);
  alert("Generated Character: " + generated_char + " Resultant Code(s): " + charcodes(generated_char));

function charcodes(invar) {
  // lists char codes for each byte in a character. 
  var ccodes = "~";
  for (ct=0; ct<invar.length; ct++){
    var invarc = invar.charCodeAt(ct);
    ccodes += invarc + "~";
  }
  return ccodes;
}
</script>

UTF-8 ページ文字セットを使用すると、次のようになります。

貼り付けた文字: [0xFFFD] 結果コード: ~65533~

生成された文字: [空白] 結果コード: ~158~

デフォルトのページ文字セットを使用すると、次のようになります。

貼り付け文字: ž 結果コード: ~382~

生成された文字: [空白] 結果コード: ~158~

特に、貼り付けられた文字の処理はどちらも正しくなく、382 のような ANSI コードはありません!

どちらの出力も 1 バイトです。

厳密に言えば、この文字は 8 ビット ASCII/ANSI であり、js はこれを処理するとは主張していませんが、テキスト ドキュメントなどから HTML エディタに貼り付けることは完全に正当です。したがって、javascript サブシステムは、バグが発生することなくそのような入力を処理できる必要があります。とにかく、2 つの異なる方法で同じ文字列を生成しても、2 つの異なる結果が返されないように思えます。

これについての考えは大歓迎です。この異常が ajax 送信の破損にどのような役割を果たしているのか正確にはわかりませんが、それが原因である可能性が高いと思われます。

4

1 に答える 1

0

ページの文字エンコーディングに関係なく、JavaScriptすべての文字列はUTF-16 (および場合によってはUSC-2の前身) です。これは、ES5 仕様のセクション8.4と ES3 のセクション 8.5 に記載されています。azなどの一般的な文字の場合、 ANSIまたはUTF-8コードが必要な場合はほとんど影響しませんが、これらは同じであるためです。ただし、これはすべての文字に当てはまるわけではありません。

ANSIを生成する場合は、256 項目の辞書または文字マッピング用のその他のロジックが必要になります。


これはそのようなテーブルです(制御文字なし)

var ANSI = {
    " ": 32,
    "!": 33,
    "\"": 34,
    "#": 35,
    "$": 36,
    "%": 37,
    "&": 38,
    "'": 39,
    "(": 40,
    ")": 41,
    "*": 42,
    "+": 43,
    ",": 44,
    "-": 45,
    ".": 46,
    "/": 47,
    "0": 48,
    "1": 49,
    "2": 50,
    "3": 51,
    "4": 52,
    "5": 53,
    "6": 54,
    "7": 55,
    "8": 56,
    "9": 57,
    ":": 58,
    ";": 59,
    "<": 60,
    "=": 61,
    ">": 62,
    "?": 63,
    "@": 64,
    "A": 65,
    "B": 66,
    "C": 67,
    "D": 68,
    "E": 69,
    "F": 70,
    "G": 71,
    "H": 72,
    "I": 73,
    "J": 74,
    "K": 75,
    "L": 76,
    "M": 77,
    "N": 78,
    "O": 79,
    "P": 80,
    "Q": 81,
    "R": 82,
    "S": 83,
    "T": 84,
    "U": 85,
    "V": 86,
    "W": 87,
    "X": 88,
    "Y": 89,
    "Z": 90,
    "[": 91,
    "\\": 92,
    "]": 93,
    "^": 94,
    "_": 95,
    "`": 96,
    "a": 97,
    "b": 98,
    "c": 99,
    "d": 100,
    "e": 101,
    "f": 102,
    "g": 103,
    "h": 104,
    "i": 105,
    "j": 106,
    "k": 107,
    "l": 108,
    "m": 109,
    "n": 110,
    "o": 111,
    "p": 112,
    "q": 113,
    "r": 114,
    "s": 115,
    "t": 116,
    "u": 117,
    "v": 118,
    "w": 119,
    "x": 120,
    "y": 121,
    "z": 122,
    "{": 123,
    "|": 124,
    "}": 125,
    "~": 126,
    " ": 127,
    "€": 128,
    " ": 129,
    "‚": 130,
    "ƒ": 131,
    "„": 132,
    "…": 133,
    "†": 134,
    "‡": 135,
    "ˆ": 136,
    "‰": 137,
    "Š": 138,
    "‹": 139,
    "Œ": 140,
    " ": 141,
    "Ž": 142,
    "«": 143,
    " ": 144,
    "‘": 145,
    "’": 146,
    "“": 147,
    "”": 148,
    "•": 149,
    "–": 150,
    "—": 151,
    "˜": 152,
    "™": 153,
    "š": 154,
    "›": 155,
    "œ": 156,
    " ": 157,
    "ž": 158,
    "Ÿ": 159,
    " ": 160,
    "¡": 161,
    "¢": 162,
    "£": 163,
    "¤": 164,
    "¥": 165,
    "¦": 166,
    "§": 167,
    "¨": 168,
    "©": 169,
    "ª": 170,
    "«": 171,
    "¬": 172,
    "­": 173,
    "®": 174,
    "¯": 175,
    "°": 176,
    "±": 177,
    "²": 178,
    "³": 179,
    "´": 180,
    "µ": 181,
    "¶": 182,
    "·": 183,
    "¸": 184,
    "¹": 185,
    "º": 186,
    "»": 187,
    "¼": 188,
    "½": 189,
    "¾": 190,
    "¿": 191,
    "À": 192,
    "Á": 193,
    "Â": 194,
    "Ã": 195,
    "Ä": 196,
    "Å": 197,
    "Æ": 198,
    "Ç": 199,
    "È": 200,
    "É": 201,
    "Ê": 202,
    "Ë": 203,
    "Ì": 204,
    "Í": 205,
    "Î": 206,
    "Ï": 207,
    "Ð": 208,
    "Ñ": 209,
    "Ò": 210,
    "Ó": 211,
    "Ô": 212,
    "Õ": 213,
    "Ö": 214,
    "×": 215,
    "Ø": 216,
    "Ù": 217,
    "Ú": 218,
    "Û": 219,
    "Ü": 220,
    "Ý": 221,
    "Þ": 222,
    "ß": 223,
    "à": 224,
    "á": 225,
    "â": 226,
    "ã": 227,
    "ä": 228,
    "å": 229,
    "æ": 230,
    "ç": 231,
    "è": 232,
    "é": 233,
    "ê": 234,
    "ë": 235,
    "ì": 236,
    "í": 237,
    "î": 238,
    "ï": 239,
    "ð": 240,
    "ñ": 241,
    "ò": 242,
    "ó": 243,
    "ô": 244,
    "õ": 245,
    "ö": 246,
    "÷": 247,
    "ø": 248,
    "ù": 249,
    "ú": 250,
    "û": 251,
    "ü": 252,
    "ý": 253,
    "þ": 254,
    "ÿ": 255
};

このページに適用された次のコードでこれを生成し、ここにいくつかの非常に小さな変更 (\とのエスケープ")をコピーして貼り付けました。使用する前に削除/削除/変更してください。\uXXXXキーの安全な文字エンコード形式に切り替えることもできます。

var cells = document.getElementsByTagName('table')[0].getElementsByTagName('td'),
    a = [], i, j, k, v;
for (j = 0; j < 7; ++j) for (i = 7 + j; i < cells.length; i += 7) {
    k = cells[i].textContent.slice(-1);
    v = +cells[i].textContent.slice(0, 3).replace(/[^\d]/g, '');
    a.push('    "' + k + '": ' + v);
}
'{\n' + a.join(',\n') + '\n}';
于 2013-09-27T00:18:45.307 に答える