从 ASP.NET 转义 JavaScript 特殊字符

Escaping JavaScript special characters from ASP.NET

本文关键字:JavaScript 特殊字符 转义 NET ASP      更新时间:2023-09-26

我的 ASP.NET 应用程序中有以下 C# 代码:

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。

编辑我使用 .Net 3.5

注意:对于此任务,您不能(也不应该(使用HTML编码器(如HttpServerUtility.HtmlEncode()(,因为HTML和JavaScript字符串的规则非常不同。一个例子:字符串"Check your Windows folder c:'windows"将被编码为"Check your Windows folder c:'windows"这显然是错误的。此外,它遵循HTML编码规则,然后它不会对''">"执行任何转义。只是为了别的东西。


如果面向 ASP.NET Core.NET 5,则应使用System.Text.Encodings.Web.JavaScriptEncoder类。


如果你的目标是.NET 4.x,你可以使用HttpUtility.JavaScriptStringEncode((方法。


如果面向 .NET 3.x 和 2.x

你必须编码什么?某些字符必须转义(''">'(,因为它们对JavaScript解析器具有特殊含义,而其他字符可能会干扰HTML解析,因此也应该转义(如果JS在HTML页面内(。你有两个转义选项: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
}

当然, 如果您将其用作转义字符,则不应对其进行转义!这种替换对于未知文本(如用户的输入或可能翻译的文本消息(很有用。请注意,如果字符串用双引号括起来,则不需要对单引号进行转义,反之亦然(。小心保留 C# 代码上的逐字字符串,否则将在 C# 中执行 Unicode 替换,客户端将收到未转义的字符串。关于干扰HTML解析的说明:现在你很少需要创建一个<script>节点并将其注入DOM中,但这是一种非常常见的技术,Web充满了像+ "</s" + "cript>"这样的代码来解决这个问题。

注意:我说转义是因为如果你的字符串包含一个转义序列(如'uxxxx't(,那么它不应该再次被转义。为此,您必须围绕此代码做一些技巧。

如果你的文本来自用户输入,并且可能是多行的,那么你也应该为此做好准备,否则你会有这样的JavaScript代码:

alert("This is a multiline
comment");

只需将.Replace("'n", "''n").Replace("'r", "")添加到以前的JavaScriptEscape()功能中即可。


为了完整性:还有另一种方法,如果你对字符串进行编码Uri.EscapeDataString()那么你可以用decodeURIComponent()在JavaScript中解码它,但这更像是一个肮脏的把戏,而不是一个解决方案。

虽然最初的问题提到了 .NET 3.5,但 4.0+ 的用户应该知道您可以使用HttpUtility.JavaScriptStringEncode("string")

第二个 bool 参数指定在结果中是包含引号 (true( 还是不包含引号 (false(。

太简单了:

@Html.Raw(myString)