2014-12-17 4 views
4

У меня следующий код C# в моем приложении ASP.NET:Escaping JavaScript специальных символов из ASP.NET

string script = @"alert('Message head:\n\n" + CompoundErrStr + " message tail.');"; 
System.Web.UI.ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "Test", script, true); 

CompoundErrStr сообщение об ошибке генерируется SQL Server (текст исключения пузырился из хранимой процедуры). Если он содержит имена столбцов таблицы, они заключены в одинарные кавычки и разрывы JavaScript во время выполнения, поскольку одинарные кавычки считаются ограничителем строк.

Как исправить для одинарных кавычек Я изменил код так:

CompoundErrStr = CompoundErrStr.Replace("'", @"\'"); 
string script = @"alert('Message head:\n\n" + CompoundErrStr + " message tail.');"; 
System.Web.UI.ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "Test", script, true); 

и теперь он работает нормально.

Однако существуют ли какие-либо другие специальные символы, которые необходимо экранировать таким образом? Есть ли функция .Net, которая может быть использована для этой цели? Что-то похожее на HttpServerUtility.HtmlEncode, но для JavaScript.

EDIT Я использую .NET 3.5

+2

Вы можете использовать тот же HttpServerUtility.HtmlEncode, который более надежный и может конвертировать любой особый символ в ковалентный HTML-код. – Sreenath

+0

@Sreenath HtmlEncode не выполняет экранирование строк JavaScript ... –

+0

Только «CompoundErrStr» должен быть закодирован до добавления в javascript. – Sreenath

ответ

5

Примечание: для выполнения этой задачи вы не можете (и не должны) использовать HTML-кодеры (например, HttpServerUtility.HtmlEncode()), потому что правила для HTML и для строк JavaScript являются довольно разные. Один пример: строка "Check your Windows folder c:\windows" будет кодироваться как "Check your Windows folder c:'windows", и это, очевидно, неправильно. Кроме того, он следует правилам кодирования HTML, то он не будет выполнять все ускользающей для \, " и ". Просто это что-то другое.

Что вы должны кодировать? Некоторые символы должны быть экранировано (\, " и '), потому что они имеют специального значения для JavaScript парсера в то время как другие могут мешать HTML разбора так должен спаслись тоже (если JS находится внутри HTML страницы). У вас есть два варианта экранирования: escape-символ JavaScript: \ или \uxxxx Кодовое обозначение Unicode (обратите внимание, что \uxxxx может использоваться для всех, но он не будет работать для символов, которые мешают анализатору HTML).

Вы можете сделать это вручную (с поиска и замены), как это:

string JavaScriptEscape(string text) 
{ 
    return text 
     .Replace("\\", @"\u005c") // Because it's JS string escape character 
     .Replace("\"", @"\u0022") // Because it may be string delimiter 
     .Replace("'", @"\u0027") // Because it may be string delimiter 
     .Replace("&", @"\u0026") // Because it may interfere with HTML parsing 
     .Replace("<", @"\u003c") // Because it may interfere with HTML parsing 
     .Replace(">", @"\u003e"); // Because it may interfere with HTML parsing 
} 

Конечно \ не должны быть экранированы, если вы используете его в качестве экранирующего символа! Это blind замена полезна для неизвестна текст (например, ввод от пользователей или текстовых сообщений, которые могут быть переведены). Обратите внимание, что если строка заключена в двойные кавычки, одинарные кавычки не нужно экранировать и наоборот). Будьте осторожны, чтобы сохранить вербальные строки в коде C# или замену Unicode на C#, и ваш клиент получит неэкранированные строки. Заметка о мешает анализу HTML: в настоящее время вам редко нужно создать узел <script> и ввести его в DOM, но это была довольно распространенная техника, и в Интернете полон код, например + "</s" + "cript>", чтобы обойти это.

Примечание: Я сказал слепой избежать, потому что, если ваша строка содержит управляющую последовательность (например, \uxxxx или \t), то он не должен быть снова бежал. Для этого вам нужно сделать некоторые трюки вокруг этого кода.

Если текст поступает из пользовательского ввода и может быть многострочным, то вы также должны быть готовы к этому или вы нарушили код JavaScript, как это:

alert("This is a multiline 
comment"); 

Просто добавьте .Replace("\n", "\\n").Replace("\r", "") к предыдущей JavaScriptEscape() функции.


Если вы ориентируетесь .NET 4 (или выше), вам не нужно делать это вручную, и вы можете непосредственно использовать вновь добавленный HttpUtility.JavaScriptStringEncode() метод.

Для полноты: есть и другой метод, если вы кодируете строку Uri.EscapeDataString(), тогда вы можете ее декодировать на JavaScript с помощью decodeURIComponent(), но это более грязный трюк, чем решение.


Если вы ориентируетесь ASP.NET Сердечник, то вы должны использовать вместо System.Text.Encodings.Web.JavaScriptEncoder.

+1

Отличный ответ! Можете ли вы пояснить, что вы подразумеваете под «слепой заменой»? –

+1

'JavaScriptEscape (@" Столбец 1 \ tColumn 2 ")' будет экранирован '' Столбец 1 \\ tColumn 2 "и' @ "\ u0032" 'станет' '\\ u0032" 'вероятно, не тем, что вы хотите. Во всяком случае, я имею в виду, что это ускользает от всего, поэтому, когда вы пишете escape-последовательность (тогда что-то нужно буквально скопировать), вам нужно будет немного обмануть ее. –

5

Хотя исходный вопрос упоминает .NET 3.5, должно быть известно пользователям 4.0+, которые вы можете использовать HttpUtility.JavaScriptStringEncode("string")

Второй параметр BOOL указывает, следует ли включать в кавычки (истинные) или нет (ложные) в результат.

Смежные вопросы