猜猜看,以下的程式碼中,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("&lt;script&gt;alert('"+msg+"');&lt;/script&gt;");
/// 中的msg有特殊字元如換行時,會造成JavaScript Error。此函數可以進行特殊字元的置換處理。
/// </summary>
///
<param name="raw">原始字串</param>
///
<param name="htmlAttribute">是否要宣告在HTML Attribute中,對單雙引號加入特別處理。
/// 例如: "&lgt;a onclick="alert('"+msg+"');"&gt;時,注意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("\"", "&quot;").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("&quot;"); else sbRet.append("\\\""); } else { sbRet.append(src[i]); } } } sbRet.append("'"); return sbRet.toString(); } }

# by player

Java版(修正版)

Post a comment