当前位置: 代码迷 >> Web前端 >> Web开发中非一般字符编码的那些事
  详细解决方案

Web开发中非一般字符编码的那些事

热度:402   发布时间:2014-01-03 00:30:09.0
Web开发中特殊字符编码的那些事
Web开发中特殊字符编码的那些事

在Web开发中,常常会遇到因为特殊字符编码的问题,引发的安全问题,或是数据正确性的问题。特总结一下:

HTML编码

HTML 中 &、"、<、>等字符有特殊含义,它们是 HTML 语言的保留字,因此不能直接使用。使用这些个字符时,应使用它们的转义序列:
&:&amp; 
" :" 
' : &#039;
< :< 
> :> 

由于 HTML 网页本身就是一个文本型结构化文档,如果直接将这些包含了 HTML 特殊字符的内容输出到网页中,极有可能破坏整个 HTML 文档的结构。所以,一般情况下需要对动态数据进行转义处理,使用转义序列表示 HTML 特殊字符。下面的 JSP 网页将一些变量动态输出到 HTML 网页中:

<%@ page language="java" contentType="text/html; charset=utf-8"%> 
<%! 
String userName = "</td><tr></table>"; 
String address = " " type="button"; 
%> 
<table border="1"> 
<tr> 
<td>姓名:</td><td><%=userName%></td> ① 
</tr> 
<tr> 
<td>年龄:</td><td>28</td> 
</tr> 
</table> 
<input value="<%=address%>" type="text" /> ② 

在 ① 和 ② 处,我们未经任何转义处理就直接将变量输出到 HTML 网页中,由于这些变量可能包含一些特殊的 HTML 的字符,它们将可能破坏整个 HTML 文档的结构。我们可以从以上 JSP 页面的一个具体输出中了解这一问题:

<table border="1"> 
<tr> 
<td>姓名:</td><td></td><tr></table></td> 
① 破坏了 <table> 的结构 
</tr> 
<tr> 
<td>年龄:</td><td>28</td> 
</tr> 
</table> 
<input value=" " type="button" type="text" /> 
② 将本来是输入框组件偷梁换柱为按钮组件

融合动态数据后的 HTML 网页已经面目全非,首先 ① 处的 <table> 结构被包含 HTML 特殊字符的 userName 变量截断了,造成其后的 <table> 代码变成无效的内容;其次,② 处 <input> 被动态数据改换为按钮类型的组件(type="button")。为了避免这一问题,我们需要事先对可能破坏 HTML 文档结构的动态数据进行转义处理。


由于 HTML 网页本身就是一个文本型结构化文档,如果直接将这些包含了 HTML 特殊字符的内容输出到网页中,极有可能破坏整个 HTML 文档的结构。所以,一般情况下需要对动态数据进行转义处理,使用转义序列表示 HTML 特殊字符。

JavaScript涉及的特殊编码

单、双引号、控制字符(制表符(tab), 反斜线(backslash), 换行(cr), 换页符(ff), etc.)

SQL特殊字符的注入
保证不要将SQL中的参数通过拼字符串的方式,就可以避免SQL注入的相关问题

常用方法:
Java端编码方法:
org.apache.commons.lang3.StringEscapeUtils
escapeEcmaScript
escapeHtml4

JavaScript端解码方法:
var decodeEntities = (function() {
	// this prevents any overhead from creating the object each time
	var element = document.createElement('div');

	function decodeHTMLEntities (str) {
		if(str && typeof str === 'string') {
			// strip script/html tags
			str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '');
			str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');
			element.innerHTML = str;
			str = element.textContent;
			element.textContent = '';
		}

		return str;
	}

	return decodeHTMLEntities;
})();
var s = decodeEntities("<script>&amp;&apos;");


Underscore.js的unescape方法

最简单的JS方法
function htmlDecode(str) {
	var s = "";
	if (str.length == 0) return "";
	s = str.replace(/&amp;/g, "&");
	s = s.replace(/</g, "<");
	s = s.replace(/>/g, ">");
	s = s.replace(/&#39;/g, "\'");
	s = s.replace(/"/g, "\"");
	return s;
}


URL编码

当一个字符串需要作为跳转的URL地址或是URL中包含的参数时,如果包含以下特殊字符,就需要做URL编码:
Dollar ("$")
Ampersand ("&")
Plus ("+")
Comma (",")
Forward slash/Virgule ("/")
Colon (":")
Semi-colon (";")
Equals ("=")
Question mark ("?")
'At' symbol ("@")
Space
Quotation marks
'Less Than' symbol ("<")
'Greater Than' symbol (">")
'Pound' character ("#")
Percent character ("%")
Left Curly Brace ("{")
Right Curly Brace ("}")
Vertical Bar/Pipe ("|")
Backslash ("\")
Caret ("^")
Tilde ("~")
Left Square Bracket ("[")
Right Square Bracket ("]")
Grave Accent ("`")

具体情况如下:
字符串是作为URL跳转的用encodeURI
字符串是作为URL的一个参数时,使用encodeURIComponent

到了Java后台时,就需要对解析的参数调用:
URLDecoder.decode(param,"utf-8");
  相关解决方案