5

このコードは nodejs v0.10.21 で壊れます

#!/usr/bin/env node
"use strict";

var urlEncoded = 'http://zh.wikipedia.org/wiki/%F0%A8%A8%8F';
var urlDecoded = decodeURI( urlEncoded );
var urlLeafEncoded = urlEncoded.substr( 29 );
var urlLeafDecoded = decodeURIComponent( urlLeafEncoded );
var urlLeafFirstCharacterDecoded = urlLeafDecoded.charAt( 0 );
var urlLeafFirstCharacterEncoded = encodeURIComponent( urlLeafFirstCharacterDecoded );

console.log( 'URL encoded = ' + urlEncoded );
console.log( 'URL decoded = ' + urlDecoded );
console.log( 'URL leaf encoded = ' + urlLeafEncoded );
console.log( 'URL leaf decoded = ' + urlLeafDecoded );
console.log( 'URL leaf first character encoded = ' + urlLeafEncoded );
console.log( 'URL leaf first character decoded = ' + urlLeafDecoded );

次のエラーが表示されます

var urlLeafFirstCharacterEncoded = encodeURIComponent( urlLeafFirstCharacterDe
                               ^
URIError: URI malformed
    at encodeURIComponent (native)
    at Object.<anonymous> (/media/data/tmp/mwoffliner/test.js:9:36)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:901:3

Javascript は以前はマルチバイト文字を正しく処理していましたが、その場合はそうではありませんでした。"%F0%A8%A8%8F" は 1 つの漢字を表しているようですが、javascript は 2 つの漢字であると認識しています。これが JavaScript ランタイムのバグなのか、エンコーディングの問題なのか、それとも私の側の誤解なのか、私は困惑しています。

4

1 に答える 1

4

は BMP の外にあり、Javascript は文字を格納するために 2 バイトしか使用しないため、サロゲート ペアとして表されます。サロゲート ペアをencodeURIComponent操作して正しい UTF8 エンコーディングを生成できますが、サロゲートを個別に読み取ることはできません。したがって、encodeURIComponent("")正常に動作しますencodeURIComponent("".charAt(0))が、失敗します。

詳細については、 http://mathiasbynens.be/notes/javascript-encodingを参照してください。また、https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponentでは、このユース ケースについて具体的に説明しています。

于 2013-11-03T13:47:09.307 に答える