Pregunta

estoy viendo un problema con algunos literales de cadena Javascript, cuando se codifica este valor:

sin codificar

<!-- 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 -->

termino con este valor:

Descifrado

"<!-- 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 -->"

, que cuando se utiliza como un javascript literal en algo de código Javascript, Firefox se queja de que es sin terminar -. Pero no puedo ver por qué a mí mismo

Por extraño que parezca, si se quita la "</script>" etiqueta de cierre del HTML anterior, la versión codificada funciona correctamente, como a continuación:

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 -->

Codificado

"<!-- 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 -->"

Este valor codificado funciona ...

Alguien sabe lo que me falta?

Actualizar

Parece bastante obvio ahora, culpar a la falta de sueño, en este caso la aplicación se basa en una versión anterior del JSON.Net para la codificación del Javascript - así que trabajé en torno al tema mediante la introducción de un nuevo JsonConverter para cuerdas, que se ocupa con escapar de etiquetas de cierre en un segundo paso después de escapar se había aplicado el código 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;
    }
}
¿Fue útil?

Solución

Bueno, sí, si tiene:

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

¿Cómo se supone que el navegador para saber que la primera </script> no es un verdadero final del elemento de guión? Cada navegador, no sólo Firefox, que leerá como:

<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

Para evitar un final prematuro a una cadena literal que contiene la secuencia </ (ETAGO), debe escapar de ella de alguna manera. Se podría decir '<\/script>' o '\x3C/script>' o incluso '<'+'/script>' (que uno es popular, aunque me parece bastante poco elegante).

Otros consejos

el valor decodificado no se emite un error en cromo o ff 3.6.10 Lo ff versión está usando?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top