标签: 零宽空格

  • 零宽空格的问题与使用

    零宽空格的问题与使用

    今天有同学在群里提问:

    “我的请求路径是这样的”
    “路径上面自动多加东西了,好奇怪”

    我的第一反应是“零宽空格”,然后该同学试着手动敲了一遍 url 地址,问题果然解决了。看起来,就是因为原来的 URL 里含有零宽空格,直接复制过来,虽然看起来没问题,但是在发起请求时,非标准字符被 encode 之后就出错了。

    我们姑且不管为啥他的复制来源里会有零宽空格,聊一聊什么是“零宽空格”,以及“零宽空格”能干什么。

    零宽空格定义

    零宽空格是空格的一种空格,但是它的宽度为零,即不显示,所以看起来跟没有一样。我们可以在浏览器里启动开发者工具,然后切换到 Console 面板,输入以下代码:

    > a = '\u200b'; // 即零宽空格
    "" // 其实是有内容的,只是看不到
    > a.length
    1 // 长度为 1,说明有东西
    > encodeURIComponent(a)
    "%E2%80%8B" // encode 之后跟截图里一样,破案了

    维基百科的解释:

    零宽空格(zero-width space, ZWSP)是一种不可打印的Unicode字符,用于可能需要换行处。

    它的用法:

    在HTML页面中,零宽空格可以替代 <wbr>。但是在一些网页浏览器(例如 Internet Explorer的版本6或以下)不支持零宽空格的功能。

    MDN 上没有零宽空格的定义,但是有 <wbr> 的内容。之前我也写过一篇文章:使用 <wbr> 解决长 URL 的换行问题,里面介绍了 HTML 换行算法,以及我选择 <wbr> 的思路,建议大家看一下。

    用途一:在特定位置换行

    比如一首古诗:

    锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦。

    我们有时候会希望:

    1. 在宽度足够的时候,放一行
    2. 如果宽度不够,就在标点符号处换行

    这个时候,我们可以先设置这段文字 word-break: keep-all,避免在汉字后断句换行;然后在每个标点后面加上零宽空格,这样,一行的时候就不会看到奇怪的空格,而宽度不够的时候,又能根据 white-space 属性正常换行。

    用途二:特殊标记

    我厂有一个产品,要输出大量日志,包含大量数字。为方便阅读,需要给数字添加千位分隔符;为了方便复制,又希望剪贴板上的是纯数字,不要千位分隔符;但是如果本来就是千位分隔符的,比如在别的软件里格式化的数字,就原样复制,不需要去掉千位分隔符。

    这个时候就可以用到零宽空格。我先找出来足够长的数字,然后添加千位分隔符,然后在两头加上零宽空格。这样在用户眼里,看到的是千位分隔过的数字;等他们复制的时候,我就检查两端的零宽空格,如果有的话,就复原数字;如果没有的话,就原样返回。

    其它零宽字符

    除了零宽空格之外,还有很多零宽字符,可以用来在页面中加入特殊标记,或者实现一些控制功能。大家如果发现 url encode 之后的内容和之前肉眼看到的不符,那么多半是存在零宽字符,可以试着干掉它们,多半问题就能解决。