raw vs. html_safe vs. h para dejar de escapar html

323

Supongamos que tengo la siguiente cadena

@x = "<a href='#'>Turn me into a link</a>"

En mi opinión, quiero que se muestre un enlace. Es decir, no quiero que todo en @x se escape y se muestre como una cadena. ¿Cuál es la diferencia entre usar

<%= raw @x %>
<%= h @x %>
<%= @x.html_safe %>

?

grautur
fuente
Como nadie lo mencionó, pensé que también mencionaría <%== @x %>que hay un alias para <%= raw(@x) %> edgeguides.rubyonrails.org/…
CTS_AE

Respuestas:

386

Considerando los rieles 3:

html_safeen realidad "establece la cadena" como HTML Safe (es un poco más complicado que eso, pero básicamente lo es). De esta manera, puede devolver cadenas seguras de HTML de los ayudantes o modelos a voluntad.

hsolo se puede usar desde un controlador o vista, ya que es de un ayudante. Obligará a la salida a escapar. En realidad no está en desuso, pero lo más probable es que ya no lo use: el único uso es "revertir" una html_safedeclaración, bastante inusual.

Anteponer su expresión rawes en realidad equivalente a llamar to_sencadenado con html_safeél, pero se declara en un asistente, al igual que h, por lo que solo se puede usar en controladores y vistas.

" SafeBuffers and Rails 3.0 " es una buena explicación sobre cómo funciona el SafeBuffers (la clase que hace la html_safemagia).

Fábio Batista
fuente
42
Yo no diría que hnunca será desaprobado. El uso "Hi<br/>#{h@ user.name}".html_safees bastante común y un uso aceptado.
maletor
1
Uso interesante de @Maletor, aunque todavía creo que pertenece a la categoría "inusual".
Fábio Batista
55
La cadena # html_safe en realidad devuelve una instancia de ActiveSupport :: SafeBuffer que envuelve la cadena original y es #html_safe? . La cadena original no se convierte en #html_safe? después de llamar a #html_safe en él.
jmaxyz
99
Tenga en cuenta que hay una sutil diferencia entre rawy html_safeen la práctica: raw(nil)devuelve una cadena vacía, mientras nil.html_safearroja una excepción.
Van der Hoorn
2
hno "revertirá" una declaración html_safe. Cuando una cadena es html_safe, hno hará nada.
GuiGS
113

Creo que vale la pena repetirlo: html_safeno no HTML escapar de su cadena. De hecho, evitará que su cadena se escape.

<%= "<script>alert('Hello!')</script>" %>

pondrá:

&lt;script&gt;alert(&#x27;Hello!&#x27;)&lt;/script&gt;

en su fuente HTML (¡sí, tan seguro!), mientras que:

<%= "<script>alert('Hello!')</script>".html_safe %>

aparecerá el cuadro de diálogo de alerta (¿estás seguro de que eso es lo que quieres?). Por lo tanto, probablemente no desee llamar html_safea ninguna cadena ingresada por el usuario.

roasm
fuente
81
En otras palabras, html_safe no es "por favor haga que este html sea seguro", es todo lo contrario: es usted el programador que le dice a los rieles que "esta cadena es html segura, ¡lo prometo!"
PaulMurrayCbr
En realidad vine aquí para averiguar si lo que realmente hace unescape o si sólo tiene una marca que no es necesario to_escape . Toda una diferencia. Ah, bueno, entonces para leer el código fuente.
Simon B.
El concepto de "html_safe" es solo un meta indicador en la cadena. Marcar algo que html_safeno se escapa ni se escapa . Si bien el resultado final de marcar algo como no seguro para HTML, y luego usar el escape implícito de la etiqueta ERB <% =, podría ser lo mismo que eliminar datos y luego volver a escapar en la salida, funcionalmente no está haciendo nada. Algo así como la diferencia de (6 * -1 * -1), vs. 6.
Ben Zittlau
46

La diferencia es entre Rails html_safe()y raw(). Hay una excelente publicación de Yehuda Katz sobre esto, y realmente se reduce a esto:

def raw(stringish)

  stringish.to_s.html_safe

end

Sí, raw()es un contenedor html_safe()que fuerza la entrada a String y luego lo invoca html_safe(). También es el caso que raw()es un ayudante en un módulo, mientras que html_safe()es un método en la clase String que crea una nueva instancia de ActiveSupport :: SafeBuffer, que tiene una @dirtybandera.

Consulte " Rails 'html_safe vs. raw ".

Pankhuri
fuente
30
  1. html_safe :

    Marca una cadena como segura de confianza. Se insertará en HTML sin realizar escapes adicionales.

    "<a>Hello</a>".html_safe
    #=> "<a>Hello</a>"
    
    nil.html_safe
    #=> NoMethodError: undefined method `html_safe' for nil:NilClass
    
  2. raw :

    rawes solo una envoltura html_safe. Úselo rawsi hay posibilidades de que la cadena sea nil.

    raw("<a>Hello</a>")
    #=> "<a>Hello</a>"
    
    raw(nil)
    #=> ""
    
  3. halias para html_escape:

    Un método de utilidad para escapar de caracteres de etiqueta HTML. Use este método para escapar de cualquier contenido inseguro.

    En Rails 3 y superiores, se usa de manera predeterminada, por lo que no necesita usar este método explícitamente

Deepak Mahakale
fuente
14

La mejor forma segura es: <%= sanitize @x %>

¡Evitará XSS!

Guilherme Y. Hatano
fuente
2

En términos de Rails simples:

h elimine las etiquetas html en caracteres numéricos para que la representación no rompa su html

html_safe establece un booleano en cadena para que la cadena se considere como html save

raw Se convierte a html_safe en cadena

usuario3118220
fuente
hes html_safedecir, el HTML se representa tal cual.
Dave Newton el
La respuesta es correcta: h es html_escape ... desde la base del código Rails
notapatch