是否有一种标准方法可以将 .NET 字符串编码为 JavaScript 字符串以在 MS Ajax 中使用?

IT技术 c# javascript asp.net ajax encoding
2021-02-28 07:45:27

我正在尝试使用RegisterStartUpScript.NET 3.5 中的 MS ScriptManager 方法将 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("\\u{0:X04}", i);
                    }
                    else
                    {
                        sb.Append(c);
                    }
                    break;
            }
        }
        sb.Append("\"");

        return sb.ToString();
    }
}

如下所述 - 原始来源:here

3个回答
Upvoted 因为它是一个很好的答案 - 虽然只适用于 .NET 4
2021-04-17 07:45:27
我认为当有一个针对特定任务的框架功能(像这样)时,它通常比自己动手做的更可靠和准确,所以最好坚持下去..
2021-05-04 07:45:27
本文展示了如何在 .NET 4之前实现它briancaos.wordpress.com/2012/05/16/...
2021-05-04 07:45:27
@eddy,问题指出 .NET 3.5,而不是 4,并且此代码仅适用于 4+。这就是为什么它不是答案。
2021-05-09 07:45:27
注意:对于那些正在寻找将国际字符编码为转义序列的方法的人来说,这行不通。有关该问题的解决方案,请参阅问题。
2021-05-12 07:45:27

具有此功能的一个问题是,它不会对封装 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>元素中使用),但它不编码&or ",因此需要进行 HTML 转义以将此类内容包含在XHTML 脚本元素需要属性值和 CDATA 包装器。

(与许多 JSON 编码器一样,它也无法对 U+2028 LINE SEPARATOR 和 U+2029 PARAGRAPH SEPARATOR 字符进行编码。由于转义所有非 ASCII 字符,上述代码确实如此。这会导致“未终止的字符串文字”错误这些字符包含在 JS 字符串文字中,因为 JavaScript 无益地将它们视为 ASCII 换行符。)

在那种情况下,您不会使用HttpUtility.HtmlAttributeEncode(HttpUtility.JavaScriptStringEncode(unencodedString))HttpUtility.HtmlEncode(HttpUtility.JavaScriptStringEncode(unencodedString))取决于上下文吗?
2021-04-30 07:45:27
写得很棒。请注意,JavaScriptSerializer它也可以通过 ASP.NET AJAX 1.0 带外版本 ( microsoft.com/downloads/en/... )在 .NET 2 中使用
2021-05-07 07:45:27
@MartinBrown:您可以使用其中任何一个来注入 JS-in-HTML-attribute,是的(尽管这样做通常是个坏主意)。HtmlEncodeHtmlAttributeEncode方法命名好奇; 似乎一个应该对属性值更好地工作,一个应该对文本内容更好地工作,但从参考源来看,实践中没有这种区别。它们只是两个任意不同实现的 HTML 编码器。
2021-05-15 07:45:27

这是一个旧线程,但您可能有兴趣了解 Microsoft AntiXSS 库,该库具有适用于 .Net 2 以后的 Javascript 编码方法。

http://msdn.microsoft.com/en-gb/security/aa973814.aspx

那个图书馆很旧。也许使用这个 System.Web.Security.AntiXss ?
2021-04-23 07:45:27
此链接不再有用。你能更新吗?
2021-05-13 07:45:27