是否有标准方法将 .NET 字符串编码为 JavaScript 字符串以在 MS Ajax 中使用?
Posted
技术标签:
【中文标题】是否有标准方法将 .NET 字符串编码为 JavaScript 字符串以在 MS Ajax 中使用?【英文标题】:Is there a standard way to encode a .NET string into JavaScript string for use in MS Ajax? 【发布时间】:2011-02-24 15:10:43 【问题描述】:我正在尝试使用 .NET 3.5 中 MS ScriptManager 的 RegisterStartUpScript
方法将 SQL Server 异常的输出传递给客户端。这适用于某些错误,但当异常包含单引号时,警报会失败。
我不想只转义单引号。我可以调用一个标准函数来转义 javascript 中使用的任何特殊字符吗?
string scriptstring = "alert('" + ex.Message + "');";
ScriptManager.RegisterStartupScript(this, this.GetType(), "Alert", scriptstring , true);
编辑:
感谢@tpeczek,代码几乎为我工作了:) 但稍作修改(单引号的转义)它就可以了。
我已在此处包含我的修改版本...
public class JSEncode
/// <summary>
/// Encodes a string to be represented as a string literal. The format
/// is essentially a JSON string.
///
/// The string returned includes outer quotes
/// Example Output: "Hello \"Rick\"!\r\nRock on"
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string EncodeJsString(string s)
StringBuilder sb = new StringBuilder();
sb.Append("\"");
foreach (char c in s)
switch (c)
case '\'':
sb.Append("\\\'");
break;
case '\"':
sb.Append("\\\"");
break;
case '\\':
sb.Append("\\\\");
break;
case '\b':
sb.Append("\\b");
break;
case '\f':
sb.Append("\\f");
break;
case '\n':
sb.Append("\\n");
break;
case '\r':
sb.Append("\\r");
break;
case '\t':
sb.Append("\\t");
break;
default:
int i = (int)c;
if (i < 32 || i > 127)
sb.AppendFormat("\\u0:X04", i);
else
sb.Append(c);
break;
sb.Append("\"");
return sb.ToString();
如下所述-原始来源:here
【问题讨论】:
【参考方案1】:这是一个旧线程,但您可能有兴趣了解 Microsoft AntiXSS 库,它具有适用于 .Net 2 及更高版本的 Javascript 编码方法。
http://msdn.microsoft.com/en-gb/security/aa973814.aspx
【讨论】:
此链接不再有用。你能更新它吗? 那个图书馆很老了。也许使用这个 System.Web.Security.AntiXss?【参考方案2】:你看过HttpUtility.JavaScriptStringEncode
吗?
【讨论】:
赞成,因为它是一个很好的答案 - 虽然仅适用于 .NET 4 我认为当有一个特定任务的框架函数(像这样)时,它通常比自己动手的更可靠和准确,所以最好坚持下去.. 这篇文章展示了如何在.NET 4之前实现它briancaos.wordpress.com/2012/05/16/… @eddy,问题指出 .NET 3.5,而不是 4,并且此代码仅适用于 4+。这就是为什么它不是答案。 注意:对于那些正在寻找一种将国际字符编码为转义序列的方法的人,这将不起作用。有关该问题的解决方案,请参阅 this question。【参考方案3】:这个函数的一个问题是它不编码通常在封装 html 时带外的字符......所以如果你试图在一个属性中包含一个带有"
的字符串,你会遇到麻烦值,或者如果您在脚本元素中有一个序列为 </script>
的字符串。这可能会导致脚本注入和 XSS。
您可以添加:
case '<':
sb.Append("\\x3C");
break;
case '"':
sb.Append("\\x22");
break;
case '&':
sb.Append("\\x26");
break;
一般来说,使用标准 JSON 编码器可能比 brew 自己的 JS 字符串文字编码器更好。这将允许您将任何简单的数据类型传递给 JS,而不仅仅是字符串。
在 .NET 3.5 中,您会得到 JavaScriptSerializer,但请注意,虽然此 确实 将 <
编码为 \u003C
(因此输出将适合在 <script>
元素中使用) ,它不编码&
或"
,因此需要HTML 转义以将此类内容包含在属性值中,并且XHTML 脚本元素需要CDATA 包装器。 p>
(与许多 JSON 编码器一样,它也无法对 U+2028 LINE SEPARATOR 和 U+2029 PARAGRAPH SEPARATOR 字符进行编码。由于转义了所有非 ASCII 字符,上述代码确实如此。这会导致 'unterminated string literal ' 当这些字符包含在 JS 字符串文字中时会出错,因为 JavaScript 无益地将它们视为 ASCII 换行符。)
【讨论】:
很棒的文章。请注意,JavaScriptSerializer
也可通过 ASP.NET AJAX 1.0 带外版本 (microsoft.com/downloads/en/…) 在 .NET 2 中使用。
在这种情况下,您不会根据上下文使用HttpUtility.HtmlAttributeEncode(HttpUtility.JavaScriptStringEncode(unencodedString))
或HttpUtility.HtmlEncode(HttpUtility.JavaScriptStringEncode(unencodedString))
吗?
@MartinBrown:您可以使用其中任何一个来注入 JS-in-HTML-attribute,是的(尽管这样做通常是个坏主意)。 HtmlEncode
和 HtmlAttributeEncode
方法的名字很奇怪;似乎一个应该更好地用于属性值,一个应该更好地用于文本内容,但是从参考来源来看,实际上并没有这种区别。它们只是两个任意不同实现的 HTML 编码器。以上是关于是否有标准方法将 .NET 字符串编码为 JavaScript 字符串以在 MS Ajax 中使用?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 .NET 标准格式字符串转换为 Excel 格式字符串