从ASP.NET转义JavaScript特殊字符

我在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生成的错误消息(从存储过程冒出的exception文本)。 如果它包含任何表列名,则它们用单引号括起来,并在执行期间中断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); 

它现在工作正常。

但是,还有其他特殊字符需要像这样转义吗? 是否有可用于此目的的.Netfunction? 类似于HttpServerUtility.HtmlEncode的东西,但是用于JavaScript。

编辑我使用.Net 3.5

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

你有什么编码 ? 某些字符必须被转义( \ ),因为它们对JavaScript解析器具有特殊意义,而其他字符可能会干扰HTML解析,因此也应该转义(如果JS在HTML页面中)。您有两种转义选项:JavaScript转义character \\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解析的注意事项:现在你很少需要创建一个节点并将其注入到DOM中,但这是一种非常常见的技术,网络上充满了像+ ""解决这个问题。

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

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

 alert("This is a multiline comment"); 

只需添加.Replace("\n", "\\n").Replace("\r", "")为以前的JavaScriptEscape()函数。


如果您的目标是.NET 4(或更高版本),则无需手动执行,您可以直接使用新添加的HttpUtility.JavaScriptStringEncode()方法。

为了完整性:还有另一种方法,如果您对字符串Uri.EscapeDataString()进行编码,那么您可以使用decodeURIComponent()在JavaScript中解码它,但这比解决方案更脏。


如果您的目标是ASP.NET Core,那么您应该使用System.Text.Encodings.Web.JavaScriptEncoder

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

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