wpadłem na tej samej rzeczy i odkrył bezpieczniejsze rozwiązanie niż korzystanie html_safe
, zwłaszcza gdy wprowadzenie ciągów, które są dynamiczne.
pierwsze, zaktualizowany kod:
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) %>
Ten ucieka long_message
treść, która jest niebezpieczna, ale pozostawia Niecytowany czy jest to bezpieczne.
Umożliwia to wyświetlanie prawidłowego wyświetlania "long message for success & such."
, ale także wymazywanie "malicious message <script>alert('foo')</script>"
.
Wyjaśnienie sprowadza się do tego - 'foo'.html_safe
zwraca ActiveSupport :: SafeBuffer który działa jak struna pod każdym względem z wyjątkiem jednego: Podczas dołączania ciąg do SafeBuffer (poprzez wywołanie + lub < <), że inny zespół jest escaped HTML przed dołączeniem do SafeBuffer. Po dodaniu innego programu SafeBuffer do programu SafeBuffer nie będzie można uniknąć jego użycia. Railsy renderują wszystkie twoje widoki pod maską za pomocą SafeBuffers, więc zaktualizowana metoda powyżej kończy się dostarczaniem Rails z SafeBuffer, który kontrolujemy, aby wykonać escaping na long_message
"w razie potrzeby" zamiast "zawsze".
Teraz zasługa tej odpowiedzi pochodzi wyłącznie od Henninga Kocha i jest opisana znacznie dokładniej pod numerem Everything you know about html_safe is wrong - moje podsumowanie powyżej próbuje jedynie podać istotę wyjaśnienia w przypadku, gdy ten link kiedykolwiek umrze.
Dzięki! Dowiedziałem się, jak to naprawić zaraz po tym, jak napisałem pytanie, ale jest to o wiele bardziej eleganckie i uproszczone. – alexy13
Znakomita odpowiedź. Nawet 15-minutowe samouczki zawsze zaskakują mnie, jak trudne są niektóre z najbardziej trywialnych zadań w Railsach. Posiadanie buldożera jest dobre i dobre, ale są chwile, wszystko czego potrzebujesz to widelec do krewetek. :) –