raw vs html_safe vs h pour annuler l'échappement html


323

Supposons que j'ai la chaîne suivante

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

À mon avis, je veux qu'un lien soit affiché. Autrement dit, je ne veux pas que tout dans @x soit échappé et affiché sous forme de chaîne. Quelle est la différence entre l'utilisation

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

?


Puisque personne ne l'a mentionné, j'ai pensé que je mentionnerais également qu'il y a <%== @x %>un alias à <%= raw(@x) %> edgeguides.rubyonrails.org/…
— CTS_AE

Réponses:


386

Considérant Rails 3:

html_safeen fait "définit la chaîne" comme HTML Safe (c'est un peu plus compliqué que ça, mais c'est fondamentalement ça). De cette façon, vous pouvez renvoyer des chaînes HTML Safe à partir d'aides ou de modèles à volonté.

hne peut être utilisé qu'à partir d'un contrôleur ou d'une vue, car il provient d'un assistant. Cela forcera la sortie à s'échapper. Ce n'est pas vraiment obsolète, mais vous ne l'utiliserez probablement plus: le seul usage est de "revenir" à une html_safedéclaration, ce qui est assez inhabituel.

Ajouter votre expression avec rawéquivaut en fait à appeler to_schaîné avec html_safe, mais est déclaré sur un assistant, tout comme h, il ne peut donc être utilisé que sur les contrôleurs et les vues.

" SafeBuffers and Rails 3.0 " est une belle explication sur le fonctionnement du SafeBuffers (la classe qui fait la html_safemagie).


42
Je ne dirais pas que cela hsera déprécié. L'utilisation "Hi<br/>#{h@ user.name}".html_safeest assez courante et une utilisation acceptée.
— maletor

1
@Maletor est une utilisation intéressante, même si je pense toujours qu'elle tombe dans la catégorie "inhabituelle".
— Fábio Batista

5
La chaîne # html_safe retourne en fait une instance d'ActiveSupport :: SafeBuffer qui enveloppe la chaîne d'origine et est #html_safe? . La chaîne d'origine ne devient pas #html_safe? après avoir appelé #html_safe dessus.
— jmaxyz

9
Notez qu'il existe une différence subtile entre rawet html_safedans la pratique: raw(nil)renvoie une chaîne vide, tout en nil.html_safelançant une exception.
— Van der Hoorn

2
hne "rétablira" pas une déclaration html_safe. Lorsqu'une chaîne est html_safe, hne fera rien.
— GuiGS

113

Je pense que cela mérite d'être répété: html_safen'échappe pas à votre chaîne HTML. En fait, cela empêchera votre chaîne de s'échapper.

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

va mettre:

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

dans votre source HTML (oui, si sûr!), tout en:

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

fera apparaître la boîte de dialogue d'alerte (êtes-vous sûr que c'est ce que vous voulez?). Donc, vous ne voulez probablement pas appeler html_safede chaînes saisies par l'utilisateur.


81
En d'autres termes, html_safe n'est pas "veuillez sécuriser ce code html", c'est le contraire - c'est vous le programmeur qui dit aux rails que "cette chaîne est sécurisée en html, promis!"
— PaulMurrayCbr

en fait, je suis venu ici pour savoir si cela permet effectivement de s'échapper ou s'il marque simplement qu'il n'est pas nécessaire de_échapper . Quelle différence. Eh bien, off pour lire le code source alors.
— Simon B.

Le concept de "html_safe" est juste un meta flag sur la chaîne. Marquage quelque chose comme html_safene pas échapper ni unescape. Bien que le résultat final du marquage de quelque chose comme non sûr pour HTML, puis de l'utilisation de l'échappement implicite de la balise ERB <% =, puisse être le même que l'échappement des données et leur rééchappement en sortie, fonctionnellement, il ne fait ni l'un ni l'autre. Un peu comme la différence de (6 * -1 * -1), contre 6.
— Ben Zittlau

46

La différence est entre Rails html_safe()et raw(). Il y a un excellent article de Yehuda Katz à ce sujet, et cela se résume vraiment à ceci:

def raw(stringish)

  stringish.to_s.html_safe

end

Oui, raw()est un wrapper html_safe()qui force l'entrée à String et l'appelle ensuite html_safe(). C'est également le cas qui raw()est un assistant dans un module tandis html_safe()qu'une méthode sur la classe String crée une nouvelle instance ActiveSupport :: SafeBuffer - qui a un @dirtyindicateur.

Reportez-vous à " Rails 'html_safe vs. raw ".


30
  1. html_safe :

    Marque une chaîne comme sécurisée de confiance. Il sera inséré dans HTML sans aucun échappement supplémentaire effectué.

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

    rawest juste un emballage autour html_safe. À utiliser raws'il y a des chances que la chaîne le soit nil.

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

    Une méthode utilitaire pour échapper les caractères de balise HTML. Utilisez cette méthode pour échapper à tout contenu dangereux.

    Dans Rails 3 et supérieur, il est utilisé par défaut, vous n'avez donc pas besoin d'utiliser cette méthode explicitement



2

En termes de Rails simples:

h supprimer les balises html en caractères numériques afin que le rendu ne casse pas votre html

html_safe définit un booléen dans la chaîne afin que la chaîne soit considérée comme une sauvegarde html

raw Il convertit en html_safe en chaîne


his html_safe, ce qui signifie que le code HTML est rendu tel quel.
— Dave Newton

La réponse est correcte: h est html_escape ... de la base de code Rails
— notapatch
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.