如何在Javascript中获取日文字符的长度?

时间:2012-07-12 14:22:51

标签: javascript unicode asp-classic cjk shift-jis

我有一个带SHIFT_JIS字符集的ASP Classic页面。页面头部下面的元标记是这样的:

<meta http-equiv="Content-Type" content="text/html; charset=shift_jis">

我的页面有一个文本框(txtName),只允许200个字符。我有一个Javascript函数来验证字符长度,这个函数在我的Submit按钮的onclick()事件中调用。

if(document.frmPage.txtName.value.length > 200) {
  alert("You have exceeded the maximum length of 200.");
  return false;
}

问题是,Javascript没有获得SHIFT_JIS中编码的日文字符的正确长度。例如,字符测量的SHIFT_JIS长度为8个字符,但Javascript只将其识别为一个字符,可能是因为默认情况下Javascript使用的Unicode编码。在SHIFT_JIS中,像ケ这样的字符有2或3个字符。

如果我只依赖于Javascript提供的长度,长日文字符将通过页面验证,它将尝试保存在数据库上,然后由于DB列的最大长度为200而失败。

我使用的浏览器是Internet Explorer。有没有办法使用Javascript获取日语字符的SHIFT_JIS长度?是否可以使用Javascript从Unicode转换为SHIFT_JIS?怎么样?

感谢您的帮助!

2 个答案:

答案 0 :(得分:8)

  

例如,字符测量的SHIFT_JIS长度为8个字符,但Javascript只将其识别为一个字符,可能是因为Unicode编码

让我们明确一点:测,U + 6D4B(汉字'测量,估计,猜想')单个字符。当您将其编码为特定编码(如Shift-JIS)时,它很可能会成为多个字节

通常,JavaScript不会使编码表可用,因此您无法找出字符占用的字节数。如果你真的需要,你必须携带足够的数据来自己解决。例如,如果您假设输入仅包含在Shift-JIS中有效的字符,则此函数将通过保留单个字节的所有字符的列表并假设每个其他字符需要来计算需要多少字节两个字节:

function getShiftJISByteLength(s) {
    return s.replace(/[^\x00-\x80。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン ゙ ゚]/g, 'xx').length;
}

然而,在Shift-JIS中没有8字节序列,并且在Shift-JIS中根本没有字符测量。 (这是在日本没有使用的中文字符。)

为什么你可能会认为它构成一个8字节的序列是这样的:当浏览器无法在表单中提交字符时,因为它在目标字符集中不存在,所以它用HTML字符引用替换它:在这种情况下&#27979;。这是一个有损的错误:您无法判断用户是按字面还是&#27979;键入的。如果您将提交的内容&#27979;显示为,则表示您忘记对输出进行HTML编码,这可能意味着您的应用程序极易受到跨站点脚本的攻击。<​​/ p>

唯一明智的答案是使用UTF-8而不是Shift-JIS。 UTF-8可以愉快地编码测量或任何其他字符,而不必使用破坏的HTML字符引用。如果您需要在数据库中存储受编码字节长度限制的内容,可以使用一个偷偷摸摸的黑客来获取字符串中的UTF-8字节数:

function getUTF8ByteLength(s) {
    return unescape(encodeURIComponent(s)).length;
}

虽然可能最好将原生Unicode字符串存储在数据库中,以便长度限制是指实际字符而不是某些编码中的字节。

答案 1 :(得分:0)

你在字符和字节之间感到困惑。测是一个字符,但你看它。在UTF-16(这是Javascript使用的)中,它是两个BYTES。在Shift_JIS中,显然是8个字节。但在这两种情况下,它都是一个角色。因此,您要做的是将文本长度限制为200 BYTES 。由于Javascript使用的是UTF-16(真的是UCS-2),你可以通过将字符串长度乘以2得到它的字节长度,但这对Shift_JIS没有帮助。再说一次,如果你正在使用Javascript ......

,你应该考虑切换到Unicode