最近项目中遇到一个跟xml非法字符有关的bug,因而了解了一下相关内容,在前端对xml非法字符进行过滤,以便前端能作更多的事情。先了解一下几个概念。javascript
xml(eXtensible Markup Language)是被设计出来传输和存储数据的语言,它的结构和html很像,而html的用途是显示数据。咱们能够在一些ajax请求的form data中看到相似的内容:php
<!--demo来着菜鸟教程-->
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="CHILDREN">
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title>Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
复制代码
这个就是xml,他就是以这种方式来传递数据。第一行为声明,代表xml版本和编码。xml可使用任何名词做为它的元素名,可是越简洁越好,避免在名称中使用“-”,“.”,“:”。能够经过元素内容或属性来携带信息。html
定义了英语字符和二进制之间的关系,用一个字节(8位)表示一个字符。一共表示128个字符,其中还包括32个不能打印的控制符号。而且只占用一个字节的后面7位,第一位为0。ASCII表对应维基百科ASCII table前端
ASCII表只能表示有限的字符,而unicode则是一个更广的字符集,码点范围从U+0000一直到U+10FFFF。几乎包括了全部的字符。而后关于unicode码的存储方式有多种,好比utf-8,utf-16,utf-32等编码方式,他们规定了怎么存储和解析unicode符号。java
在javascript中可使用unicode表示字符。在es6以前,可使用\uxxxx
的方式来表示\u0000
~uffff
之间的符号。超过这个范围的就要使用两个双字节来表示。而es6以后,能够经过一个大括号来表示任何的unicode符号。好比 \u{23333}
es6
console.log('\u0061')
// a
console.log('\u{61}')
// a
复制代码
而且es6还实现了正则表达式对u
修饰符的支持,含义为Unicode模式
,能够直接匹配大于\ufff
的字符。ajax
sWords = sWords.replace(/\u{23333}/u,"")
复制代码
了解了这些东西以后就能够对咱们的xml进行非法字符的过滤了。首先咱们查看一下xml1.0版本(目前针对1.0)的字符范围:正则表达式
#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
复制代码
那么不在这个范围里面的属于xml非法字符了,并且这么巧,大于uffff
的符号都支持,而后不支持的符号咱们能够经过正则去把他们过滤掉:ui
sXml = sXml.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\ud800-\udfff\ufffe\uffff]/g, "")
复制代码
这样咱们就把xml1.0不支持的符号过滤掉了。其余版本同理。编码