是否有标准方法将 .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 时带外的字符......所以如果你试图在一个属性中包含一个带有" 的字符串,你会遇到麻烦值,或者如果您在脚本元素中有一个序列为 &lt;/script&gt; 的字符串。这可能会导致脚本注入和 XSS。

您可以添加:

            case '<':
                sb.Append("\\x3C");
                break;
            case '"':
                sb.Append("\\x22");
                break;
            case '&':
                sb.Append("\\x26");
                break;

一般来说,使用标准 JSON 编码器可能比 brew 自己的 JS 字符串文字编码器更好。这将允许您将任何简单的数据类型传递给 JS,而不仅仅是字符串。

在 .NET 3.5 中,您会得到 JavaScriptSerializer,但请注意,虽然此 确实&lt; 编码为 \u003C(因此输出将适合在 &lt;script&gt; 元素中使用) ,它编码&amp;",因此需要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,是的(尽管这样做通常是个坏主意)。 HtmlEncodeHtmlAttributeEncode 方法的名字很奇怪;似乎一个应该更好地用于属性值,一个应该更好地用于文本内容,但是从参考来源来看,实际上并没有这种区别。它们只是两个任意不同实现的 HTML 编码器。

以上是关于是否有标准方法将 .NET 字符串编码为 JavaScript 字符串以在 MS Ajax 中使用?的主要内容,如果未能解决你的问题,请参考以下文章

java中的编码转换

如何将 .NET 标准格式字符串转换为 Excel 格式字符串

如何在Visual Studio中设置标准编码

将版本嵌入 Python 包的标准方法?

是否有一个 JDK 类来进行 HTML 编码(但不是 URL 编码)?

java中的char函数怎么用