2010-10-14 27 views
44

rails 3 parece escaparse de todo, incluso html. He intentado usar raw() pero todavía escapa html. ¿Hay alguna solución? Esta es mi ayudador que estoy usando (/helpers/application_helper.rb):No escapes html en ruby ​​on rails

module ApplicationHelper 
    def good_time(status = true) 
    res = "" 
    if status == true 
     res << "Status is true, with a long message attached..." 
    else 
     res << "Status is false, with another long message" 
    end 
    end 
end 

Estoy llamando al ayudante en mi opinión, el uso de este código:

<%= raw(good_time(true)) %> 

Respuesta

80

Usted puede utilizar .html_safe como esto:

def good_time(status = true) 
    if status 
    "Status is true, with a long message attached...".html_safe 
    else 
    "Status is false, with another long message".html_safe 
    end 
end 

<%= good_time(true) %> 
+1

¡Gracias! Descubrí una forma de solucionarlo justo después de publicar la pregunta, pero esto es mucho más elegante y simplista. – alexy13

+10

Excelente respuesta. Sin importar los tutoriales de 15 minutos, siempre me sorprende lo difícil que son algunas de las tareas más triviales en Rails. Tener un bulldozer está muy bien, pero a veces lo único que necesitas es un tenedor de camarones. :) –

3

me encontré con esta misma cosa y descubrieron una solución más seguro que usar html_safe, especialmente una vez que se introduce cadenas que son dinámicos.

En primer lugar, el código de actualización:

def good_time(long_message1, long_message2, status = true) 
    html = "".html_safe 
    html << "Status is #{status}, " 
    if status 
    html << long_message1 
    else 
    html << long_message2 
    end 
    html 
end 

<%= good_time(true) %> 

Esta escapa long_message contenido si no es seguro, pero lo deja literalmente de forma si es seguro.

Esto permite "long message for success & such." para mostrar correctamente, pero también se escapa "malicious message <script>alert('foo')</script>".

La explicación se reduce a esto - 'foo'.html_safe devuelve un ActiveSupport :: SafeBuffer que actúa como una cadena en todos los sentidos, excepto uno: Al añadir una cadena a un SafeBuffer (llamando al + o < <), que otra cadena está escapado en HTML antes de ser anexado a SafeBuffer. Cuando agrega otro SafeBuffer a SafeBuffer, no se producirá ningún escape. Rails está visualizando todas sus vistas bajo el capó utilizando SafeBuffers, por lo que el método actualizado anterior proporciona a Rails un SafeBuffer que hemos controlado para realizar escapes en el long_message "según sea necesario" en lugar de "siempre".

Ahora, el mérito de esta respuesta corresponde enteramente a Henning Koch, y se explica con más detalle en Everything you know about html_safe is wrong - mi resumen anterior solo intenta dar la esencia de la explicación en caso de que este enlace muera alguna vez.

+0

Esto no tiene mucho sentido, porque escapará * todo * HTML en 'long_message1' y' long_message2'. El asker parece querer permitir algo de HTML. Puede hacerlo llamando a '.html_safe' en la cadena, pero obviamente solo debería hacer eso si puede confiar en la cadena. Lo que sugieres no permitirá HTML, se escapará todo. Por favor corrígeme si estoy equivocado. – Mischa

+0

@Mischa Esto no escapa a todo el HTML en 'long_message1' y' long_message2' - ese es el punto. :-) El comportamiento de concatenación de SafeBuffer solo escapa el contenido si no es seguro. En mi respuesta, incluyo un ejemplo con '&', que es * no * escapado correctamente, y se muestra como '&' (no '&'). Además, si le interesan más ejemplos y detalles, tenga en cuenta el enlace a la explicación completa de Henning Koch. – DreadPirateShawn

+0

Gracias. Creo que tengo que echar un vistazo más profundo a SafeBuffer. Me pregunto cómo determina qué es seguro y qué no. Por ejemplo, ¿qué pasa si asker quiere tener un enlace en su mensaje? ¿Permitiría eso en su implementación? – Mischa