in 未分类

textarea 中的计数在前端和后端之间的差别

计算 textarea 中用户输入字符的个数,给出用户提示,并在前端和后端同时校验长度是非常常见的需求。但是在前端和后端,对于带有换行的文本的长度计算却有一点出入。

简单的说来,在前端和后端如果都直接计算字符的长度,那么,一个换行,在前端,长度计算是1,而在后端计算出来是2。

我写了个简单的 DEMO ,你可以点开看看,注意查看源代码。截图如下:

我们可以看到第三个字符对应的 unicode 编码,然后我们到 http://www.unicode.org/charts/PDF/U0000.pdf 这里来查看编码对应的字符,可以看到 61 对应的是字符”a”, a 对应 “NL(new line)”,62 对应的是字符“b” ,也就是说在 a 和 b 之间只有一个“NL”,所以,我们计算的长度为 5。

接着,我们提交表单试试,打开调试工具,选择录制请求,可以看到如下的结果:

可以看到,提交表单的时候,换行符就变成了 %0D%0A , 我们可以查到这两个字符对应的是 “CR(carriage return)” 和 “NL(new line)” ,所有后端在计算这个长度的时候,就变成 6 了。

那知道这个问题的存在了,解决办法就有好几种了,你可以在前端计算 length 的时候,把 \n 替换成 \r\n 再计算,和后端保持一致,也可以在后端做替换和前端保持一致。也可以在前后端都忽略掉换行符。具体的方法取决于你的业务场景。

感谢 xj.ye 的评论,在不同浏览器下表现也是不一致的,主要是 IE 和其他浏览器的区别。

  1. 你的submit没有起效,跳转的是#,貌似并没有把Post过去的东西接收。你用tag的名字,但是没有用name=”text”,post能够把里面的变量传承testarea么??

    另外一个问题是,我记得在windows里面\r\n表示换行回车,而在Linux\Unix里面\n已经是表示换行回车了,所以我怀疑是不是操作系统的问题?比如windows下的chrome跟linux下的chrome在处理换行回车的时候,用的是不同的做法?
    或者是因为替换的时候,默认把\n直接换成%0D%0A ?但是我记得只有><%&这些html用的tag才会替换的说……

    再另外一个问题,为啥要连这些换行回车之类的符号都要检查?是不是数据库存下来的时候,需要校对?因为我个人觉得每个str.strip()的数目对等就可以了……

    • 这个和浏览器的关系比较大。 LS 提醒,在 IE6,7,8 下表现可能不一致,改天我再仔细测下。

      submit 起效了,就是提交到当前 URL ,因为我没有写相应的后端程序,所以直接提交到当前 URL ,从浏览器debug工具中看提交的内容。

      检查这些字符的目的是为了计算用户输入文字的长度,比如新浪微博,只能输入 140 字,所以在前端和后端都要做这个长度校验。如果前端认为用户输入的长度是 140 ,而后端接收到后,认为是 141 个字符,那要么 reject 这次请求,要么截取字符串,无论如何操作,用户体验都不好。

      • 我没有用debug工具看,囧……
        你的意思是,用户输入完之后,马上检查字符数对不对,而不是到后面等服务器返回之后再显示,我的理解对吧?

        • 对,我说的就是这个意思。比如你看 twitter 和新浪微博的消息发布框,都有这个计数提示,这个还是蛮常见的需求。