KB-Javascript字串的特殊字元處理
6 |
猜猜看,以下的程式碼中,jsAlert函式有什麼"可議之處"?
private void Page_Load(object sender, System.EventArgs e)
{
string msg="Hello, World!";
jsAlert(msg);
}
private void jsAlert(string msg)
{
Response.Write("<script>alert(\""+msg+"\");</script>");
Response.Write("<button onclick=\"alert('"+msg+"');\">CLICK</button>");
}
問題出在,當msg參數含有一些特殊字元時,這個網頁有可能產生JavaScript Error。
例如: 若msg="L1\r\nL2\rL3\n<Words>\"It's good!\"</Words>",其中的換行及雙引號會造成<script>列出錯,而單引號及換行則會讓<button>列掛點。
簡單來說,當傳入的參數要形成Javascript的字串內容時,我們要特別留意換行及單雙引號這些特殊字元。廢話不多說,我寫了個函數來處理,大家直接看Code就明白。我想得到,該攔的應該都攔了,沒想到的就有勞大家集思廣義,多多檢舉了。
private void betterJsAlert(string msg)
{
Response.Write("<script>alert('"+JSStringEscape(msg,false)+"');</script>");
Response.Write("<button onclick=\"alert('"+JSStringEscape(msg,true)+"');\">CLICK</button>");
}
/// <summary>
/// 字串要被宣告成JavaScript字串時的特殊處理。例如: Response.Write("<script>alert('"+msg+"');</script>");
/// 中的msg有特殊字元如換行時,會造成JavaScript Error。此函數可以進行特殊字元的置換處理。
/// </summary>
/// <param name="raw">原始字串</param>
/// <param name="htmlAttribute">是否要宣告在HTML Attribute中,對單雙引號加入特別處理。
/// 例如: "&lgt;a onclick="alert('"+msg+"');">時,注意Attribute請使用雙引號包含字串</param>
/// <returns>置換特殊字元之後的字串</returns>
/// <remarks></remarks>
private string JSStringEscape(string raw, bool inHtmlAttribute)
{
raw=raw.Replace("\r\n","\\n").Replace("\r","").Replace("\n","\\n");
if (inHtmlAttribute)
raw=raw.Replace("\"", """).Replace("'", "\\'");
else
raw=raw.Replace("'","\\'").Replace("\"","\\\"");
return raw;
}
private void Page_Load(object sender, System.EventArgs e)
{
string msg="Hello, World!";
jsAlert(msg);
}
private void jsAlert(string msg)
{
Response.Write("<script>alert(\""+msg+"\");</script>");
Response.Write("<button onclick=\"alert('"+msg+"');\">CLICK</button>");
}
問題出在,當msg參數含有一些特殊字元時,這個網頁有可能產生JavaScript Error。
例如: 若msg="L1\r\nL2\rL3\n<Words>\"It's good!\"</Words>",其中的換行及雙引號會造成<script>列出錯,而單引號及換行則會讓<button>列掛點。
簡單來說,當傳入的參數要形成Javascript的字串內容時,我們要特別留意換行及單雙引號這些特殊字元。廢話不多說,我寫了個函數來處理,大家直接看Code就明白。我想得到,該攔的應該都攔了,沒想到的就有勞大家集思廣義,多多檢舉了。
private void betterJsAlert(string msg)
{
Response.Write("<script>alert('"+JSStringEscape(msg,false)+"');</script>");
Response.Write("<button onclick=\"alert('"+JSStringEscape(msg,true)+"');\">CLICK</button>");
}
/// <summary>
/// 字串要被宣告成JavaScript字串時的特殊處理。例如: Response.Write("<script>alert('"+msg+"');</script>");
/// 中的msg有特殊字元如換行時,會造成JavaScript Error。此函數可以進行特殊字元的置換處理。
/// </summary>
/// <param name="raw">原始字串</param>
/// <param name="htmlAttribute">是否要宣告在HTML Attribute中,對單雙引號加入特別處理。
/// 例如: "&lgt;a onclick="alert('"+msg+"');">時,注意Attribute請使用雙引號包含字串</param>
/// <returns>置換特殊字元之後的字串</returns>
/// <remarks></remarks>
private string JSStringEscape(string raw, bool inHtmlAttribute)
{
raw=raw.Replace("\r\n","\\n").Replace("\r","").Replace("\n","\\n");
if (inHtmlAttribute)
raw=raw.Replace("\"", """).Replace("'", "\\'");
else
raw=raw.Replace("'","\\'").Replace("\"","\\\"");
return raw;
}
Comments
# by steve
大師有沒有被 parseInt("08") 扁過?<BR/>還蠻痛的.....
# by Darkthread
所幸沒被扁過,不過看起來應該很痛!!<BR/>0x就算了,用0開頭似乎不是好的In-band表示法,這樣看來,寫程式時的陷阱可多了!
# by steve
事情是這樣的<BR/>DateTime欄位日期格式轉換麻煩->不想使用DateTime格式->使用字串儲存日期(20060801)->月份日期出現0開頭->使用cint或parseInt將0去掉並且拿來做運算.....
# by player
string JSStringEscape(string raw, bool inHtmlAttribute) 好東西 我偷來用囉 拿來改進 class JavaScriptTool
# by player
//Java版(還沒測過) public class SafeJSString { public static final String Escape(String strData, Boolean inHtmlAttribute) { java.lang.StringBuffer sbRet = new java.lang.StringBuffer(); sbRet.append("'"); if (strData != null) { char [] src = strData.toCharArray(); for(int i=0; i<src.length; i++) { //if(String.valueOf(src[i]).equals("\r\n")) //{ // sbRet.append("\\n"); //} //else if(String.valueOf(src[i]).equals("\r")) { //sbRet.append(""); } else if(String.valueOf(src[i]).equals("\n")) { sbRet.append("\\n"); } else if(String.valueOf(src[i]).equals("'")) { sbRet.append("\\'"); } else if(String.valueOf(src[i]).equals("\"")) { if (inHtmlAttribute == true) sbRet.append("""); else sbRet.append("\\\""); } else { sbRet.append(src[i]); } } } sbRet.append("'"); return sbRet.toString(); } }
# by player
Java版(修正版)