2010-11-08 91 views
2

我看到一個問題,與一些JavaScript字符串文字,編碼此值時:未結束的字符串在JavaScript字符串中逃脫HTML文字

非編碼

<!-- Start ValueClick Media 300x250 Code for Test Tag --> 
<script language="javascript" src="http://media.fastclick.net/w/get.media?sid=38901&m=6&tp=8&d=j&t=n"></script> 
<noscript><a href="http://media.fastclick.net/w/click.here?sid=38901&m=6&c=1" target="_blank"> 
<img src="http://media.fastclick.net/w/get.media?sid=38901&m=6&tp=8&d=s&c=1"width=300 height=250 border=1></a></noscript> 
<!-- End ValueClick Media 300x250 Code for Test Tag --> 

我結束了這個值:

解碼

"<!-- Start ValueClick Media 300x250 Code for Test Tag -->\r\n<script language=\"javascript\" src=\"http://media.fastclick.net/w/get.media?sid=38901&m=6&tp=8&d=j&t=n\"></script>\r\n<noscript><a href=\"http://media.fastclick.net/w/click.here?sid=38901&m=6&c=1\" target=\"_blank\">\r\n<img src=\"http://media.fastclick.net/w/get.media?sid=38901&m=6&tp=8&d=s&c=1\"width=300 height=250 border=1></a></noscript>\r\n<!-- End ValueClick Media 300x250 Code for Test Tag -->" 

當在某些JavaScript代碼中用作JavaScript文字時,Firefox抱怨它沒有終止 - 但我看不出爲什麼是我自己。

奇怪的是,如果我從上面的HTML刪除 「</script>」 關閉標籤,編碼版本可以正常工作,如下圖所示:

Unecoded

<!-- Start ValueClick Media 300x250 Code for Test Tag --> 
<script language="javascript" src="http://media.fastclick.net/w/get.media?sid=38901&m=6&tp=8&d=j&t=n"> 
<noscript><a href="http://media.fastclick.net/w/click.here?sid=38901&m=6&c=1" target="_blank"> 
<img src="http://media.fastclick.net/w/get.media?sid=38901&m=6&tp=8&d=s&c=1"width=300 height=250 border=1></a></noscript> 
<!-- End ValueClick Media 300x250 Code for Test Tag --> 

編碼

"<!-- Start ValueClick Media 300x250 Code for Test Tag -->\r\n<script language=\"javascript\" src=\"http://media.fastclick.net/w/get.media?sid=38901&m=6&tp=8&d=j&t=n\">\r\n<noscript><a href=\"http://media.fastclick.net/w/click.here?sid=38901&m=6&c=1\" target=\"_blank\">\r\n<img src=\"http://media.fastclick.net/w/get.media?sid=38901&m=6&tp=8&d=s&c=1\"width=300 height=250 border=1></a></noscript>\r\n<!-- End ValueClick Media 300x250 Code for Test Tag -->" 

此編碼值可以工作...

任何人都知道我錯過了什麼?

更新

現在看來相當明顯的,都怪我睡眠不足,在這種情況下,應用程序是依靠JSON.Net的較舊版本編碼的JavaScript - 所以我工作圍繞這一問題通過引入一個新的用於字符串的JsonConverter,它在應用了JavaScript轉義之後的第二遍中處理了轉義結束標記。

public class EscapeTagsStringConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     if (value == null) 
     { 
      writer.WriteNull(); 
      return; 
     } 

     string escapedValue = ToEscapedJavaScriptString(value.ToString(), '"').Replace("</", "<\\/"); 

     writer.WriteRawValue("\"" + escapedValue + "\""); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer) 
    { 
     return reader.Value.ToString(); 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof (string)); 
    } 

    public static char IntToHex(int n) 
    { 
     if (n <= 9) 
     { 
      return (char)(n + 48); 
     } 
     return (char)((n - 10) + 97); 
    } 

    public static void WriteCharAsUnicode(TextWriter writer, char c) 
    { 
     char h1 = IntToHex((c >> 12) & '\x000f'); 
     char h2 = IntToHex((c >> 8) & '\x000f'); 
     char h3 = IntToHex((c >> 4) & '\x000f'); 
     char h4 = IntToHex(c & '\x000f'); 

     writer.Write('\\'); 
     writer.Write('u'); 
     writer.Write(h1); 
     writer.Write(h2); 
     writer.Write(h3); 
     writer.Write(h4); 
    } 

    public static void WriteEscapedJavaScriptChar(TextWriter writer, char c, char delimiter) 
    { 
     switch (c) 
     { 
      case '\t': 
       writer.Write(@"\t"); 
       break; 
      case '\n': 
       writer.Write(@"\n"); 
       break; 
      case '\r': 
       writer.Write(@"\r"); 
       break; 
      case '\f': 
       writer.Write(@"\f"); 
       break; 
      case '\b': 
       writer.Write(@"\b"); 
       break; 
      case '\\': 
       writer.Write(@"\\"); 
       break; 
      case '\'': 
       writer.Write((delimiter == '\'') ? @"\'" : @"'"); 
       break; 
      case '"': 
       writer.Write((delimiter == '"') ? "\\\"" : @""""); 
       break; 
      default: 
       if (c > '\u001f') 
        writer.Write(c); 
       else 
        WriteCharAsUnicode(writer, c); 
       break; 
     } 
    } 

    public void WriteEscapedJavaScriptString(TextWriter writer, string value, char delimiter) 
    { 
     if (value != null) 
     { 
      for (int i = 0; i < value.Length; i++) 
      { 
       WriteEscapedJavaScriptChar(writer, value[i], delimiter); 
      } 
     } 
    } 

    public string ToEscapedJavaScriptString(string value) 
    { 
     return ToEscapedJavaScriptString(value, '"'); 
    } 

    public string ToEscapedJavaScriptString(string value, char delimiter) 
    { 
     using (StringWriter w = CreateStringWriter(GetLength(value) ?? 16)) 
     { 
      WriteEscapedJavaScriptString(w, value, delimiter); 
      return w.ToString(); 
     } 
    } 

    public static StringWriter CreateStringWriter(int capacity) 
    { 
     StringBuilder sb = new StringBuilder(capacity); 
     StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture); 

     return sw; 
    } 

    public static int? GetLength(string value) 
    { 
     if (value == null) 
      return null; 
     return value.Length; 
    } 
} 
+0

嘗試 zzzzBov 2010-11-08 19:49:17

回答

4

嗯,是的,如果您有:

<script> 
    var s= '</script>'; 
</script> 

如何在瀏覽器應該知道的是,第一</script>是不是腳本元素的真正結束?每一個瀏覽器,不只是火狐,將讀取爲:

<script> 
    var s= ' // uh-oh! string literal left open! 
</script>'; // script element closed. Then some trailing text content 
</script>  // close-tag for a script that isn't open, ignore 

爲了避免過早地結束含有</(ETAGO)序列的字符串文字,你必須以某種方式逃避它。你可以說'<\/script>''\x3C/script>'甚至'<'+'/script>'(這是一個流行的,但我覺得它相當不雅)。

+0

感謝,正是我一直在尋找中添加空間 - 似乎很明顯,一旦我再次查找 – Bittercoder 2010-11-09 10:20:03

+0

其本身而言,ETAGO分隔符不關閉包含元素(甚至儘管HTML 4.01規範似乎暗示如此)。(@ bobince知道這一點,但是由於他的回答沒有提到這一點,我只是在這裏指出它以備將來參考。)我做了一些關於這個主題的研究並在這裏發表了我的發現:http://mathiasbynens.be/notes/etago – 2011-06-29 11:04:16

0

解碼值不3.6.10 什麼FF的版本您使用的鍍鉻或FF拋出一個錯誤?