Существует ли стандартный способ кодирования строки .NET в строку JavaScript для использования в MS Ajax?

65

Я пытаюсь передать результат исключения SQL Server клиенту, используя метод RegisterStartUpScript MS ScriptManager в .NET 3.5. Это работает отлично для некоторых ошибок, но когда исключение содержит одинарные кавычки, предупреждение не работает.

Я не хочу только избегать одиночных кавычек. Есть ли стандартная функция, которую я могу вызвать, чтобы избежать каких-либо специальных символов для использования в 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();
    }
}

Как упоминалось ниже - исходный источник: здесь

Теги:
encoding

3 ответа

155

Вы посмотрели HttpUtility.JavaScriptStringEncode?

  • 9
    Upvoted, потому что это отличный ответ - работает только в .NET 4, хотя
  • 5
    Я думаю, что когда есть рамочная функция для конкретной задачи (как эта), она часто более надежна и точна, чем самостоятельная, поэтому лучше придерживаться ее…
Показать ещё 9 комментариев
9

Пробем с этой функцией состоит в том, что он не кодирует символы, которые обычно не входят в диапазон при инкапсуляции HTML... поэтому у вас возникнут проблемы, если вы попытаетесь включить строку с " внутри атрибута значение, или если у вас была строка с последовательностью </script> внутри элемента script. Это может привести к 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 script.

(Как и многие JSON-кодеры, он также не может кодировать символы UL + 2028 LINE SEPARATOR и U + 2029 PARAPRAPH SEPARATOR. Вышеприведенный код делает это из-за экранирования всех символов, отличных от ASCII. Это приводит к "неинициализированному строковому литералу ошибки, когда эти символы включены в строковый литерал JS, потому что JavaScript бесполезно относится к ним так же, как к новой строке ASCII.)

  • 1
    Отличная рецензия. Обратите внимание, что JavaScriptSerializer также доступен в .NET 2 через внеполосный выпуск ASP.NET AJAX 1.0 ( microsoft.com/downloads/en/… ).
  • 1
    В этом случае вы бы не использовали HttpUtility.HtmlAttributeEncode(HttpUtility.JavaScriptStringEncode(unencodedString)) или HttpUtility.HtmlEncode(HttpUtility.JavaScriptStringEncode(unencodedString)) зависимости от контекста?
Показать ещё 1 комментарий
3

Это старый поток, но вам может быть интересно узнать о библиотеке Microsoft AntiXSS, которая имеет метод кодирования Javascript, который работает для .Net 2 и далее.

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

  • 0
    Эта ссылка больше не полезна. Вы можете обновить его?
  • 0
    Эта библиотека была довольно старой. Использовать этот System.Web.Security.AntiXss возможно?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню