Недопустимый персонаж, нарушающий сценарий
Я использую этот код для создания строки кода JavaScript и запускаю их из кода C# позади.
Он работает нормально для нормальных значений, но разрывается, когда ' (апостроф) присутствует в значениях.
StringBuilder sb = new StringBuilder();
sb.Append("<script>");
// Store transmission chrome feature.
for(int i=0; i < Transmission.Length; i++)
{
sb.Append("var obj = {text: '" + Transmission[i][0] + "',"
+ "value: '" + Transmission[i][1] +"'};");
sb.Append("transChromeData.push(obj);");
}
sb.Append("</" + "script>");
this.RegisterStartupScript("Info", sb.ToString());
3 ответа
Это также сломается, если кто-то добавляет \
в качестве значения. Вам нужно экранировать символы, которые будут разбивать строку Javascript - HttpUtility.JavaScriptStringEncode сделает это за вас:
StringBuilder sb = new StringBuilder();
sb.Append("<script>");
// Store transmission chrome feature.
for(int i=0; i < Transmission.Length; i++)
{
sb.Append("var obj = {text: '" + HttpUtility.JavaScriptStringEncode(Transmission[i][0]) + "',"
+ "value: '" + HttpUtility.JavaScriptStringEncode(Transmission[i][2]) +"'};");
sb.Append("transChromeData.push(obj);");
}
sb.Append("</" + "script>");
this.RegisterStartupScript("Info", sb.ToString());
Для архаичных версий.NET вам нужно накатить свои собственные. Rick Strahl имеет хорошую реализацию, которая охватывает различные символы JS:
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 '\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();
}
Попробуй это:
StringBuilder sb = new StringBuilder();
sb.Append("<script>");
// Store transmission chrome feature.
for (int i = 0; i < Transmission.Length; i++)
{
sb.Append("var obj = {text: '")
.Append(Escape(Transmission[i][0]))
.Append("',")
.Append("value: '")
.Append(Escape(Transmission[i][1]))
.Append("'};")
.Append("transChromeData.push(obj);");
}
sb.Append("</script>");
this.RegisterStartupScript("Info", sb.ToString());
...
static string Escape(string source)
{
return source.Replace(@"'", @"\'");
}
Использовать функцию экранирования Microsoft JScript
Microsoft.JScript.GlobalObject.escape("String to escape");
под вашим кодом отредактировано
StringBuilder sb = new StringBuilder();
sb.Append("<script>");
// Store transmission chrome feature.
for(int i=0; i < Transmission.Length; i++)
{
sb.Append("var obj = {text: '" + Microsoft.JScript.GlobalObject.escape(Transmission[i][0]) + "',"
+ "value: '" + Microsoft.JScript.GlobalObject.escape(Transmission[i][1]) +"'};");
sb.Append("transChromeData.push(obj);");
}
sb.Append("</" + "script>");
this.RegisterStartupScript("Info", sb.ToString());
В качестве альтернативы вы можете использовать
HttpUtility.UrlDecode
но это будет небезопасно
на asp.net 1.1 попробуйте использовать код, предложенный здесь http://www.west-wind.com/weblog/posts/2007/Jul/14/Embedding-JavaScript-Strings-from-an-ASPNET-Page