je suis tombé sur cette même chose et a découvert une solution plus sûre que l'utilisation html_safe
, en particulier une fois que vous introduisez des chaînes qui sont dynamiques.
D'abord, le code mis à jour:
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) %>
Ce échappe long_message
contenu si elle est dangereuse, mais laisse unescape s'il est sûr.
Ceci permet "long message for success & such."
d'afficher correctement, mais aussi échappe "malicious message <script>alert('foo')</script>"
.
L'explication se résume à ceci - 'foo'.html_safe
retourne un ActiveSupport :: SafeBuffer qui agit comme une chaîne dans tous les sens, sauf un: Lorsque vous ajoutez une chaîne à un SafeBuffer (en appelant + ou < <), que d'autres cordes HTML est échappé avant d'être ajouté au SafeBuffer. Lorsque vous ajoutez un autre SafeBuffer à un SafeBuffer, aucun échappement ne se produira. Rails rend toutes vos vues sous le capot en utilisant SafeBuffers, donc la méthode mise à jour ci-dessus finit par fournir à Rails un SafeBuffer que nous avons contrôlé pour effectuer l'échappement sur le long_message
"selon les besoins" plutôt que "toujours". Maintenant, le crédit pour cette réponse va entièrement à Henning Koch, et est expliqué de manière beaucoup plus détaillée au Everything you know about html_safe is wrong - mon récapitulatif ci-dessus tente seulement de fournir l'essence de l'explication dans le cas où ce lien meurt jamais.
Merci! J'ai trouvé un moyen de le réparer juste après avoir posté la question, mais c'est beaucoup plus élégant et simpliste. – alexy13
Réponse exceptionnelle. Malgré les tutoriels de 15 minutes, il m'étonne toujours de voir à quel point certaines des tâches les plus triviales sont difficiles dans Rails. Avoir un bulldozer est très bien, mais il y a des fois où vous avez besoin d'une fourchette de crevettes. :) –