Javascript charAt()破坏多字节字符字符串

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"表示一个中文字符,但JavaScript认为它们是两个字符。我不知道这是否是JavaScript运行时的错误,还是某种编码问题,或者是我的误解。


1
var char = '';,现在 char.length === 2char.charCodeAt(0) === 55394char.charCodeAt(1) === 56847,尽管它只显示为一个字符。 - Paul S.
1个回答

5
位于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专门记录了这种用法。


非常感谢您的解释,这对我有很大帮助。Mozilla 提供了一个 "固定" 版本的 string.charAt(),可以解决我的问题: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/charAt - user2949756

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