Як кодувати HTML / виводити рядок? Чи є вбудований?


98

У мене є ненадійний рядок, який я хочу показати як текст на сторінці HTML. Мені потрібно уникнути символів ' <' і ' &' як HTML-сутності. Чим менше метушні, тим краще.

Я використовую UTF8 і мені не потрібні інші сутності для наголошених літер.

Чи є вбудована функція в Ruby або Rails, чи я повинен прокручувати власну?


2
Відповідно до OWASP , для належного захисту XSS у вмісті елемента HTML слід &<>"'/
уникати

Відповіді:


94

hДопоміжний метод:

<%=h "<p> will be preserved" %>

Що ж, він також уникає>, що непотрібно, але це зробить.
кч

Ви можете використовувати дужки для друку деяких з h, а деяких без. <% = h ("<p") + ">"%>
Тревор Брамбл

Тепер це було б нерозумно. Мене мало хвилює, врятується він чи ні. Я просто зауважую, що це не потрібно в специфікаціях html.
кч

12
Це іноді потрібно в XHTML з - за досить дратівливою наполегливістю XML - SPEC, що «]]>» бути видалені з тексту (див виробництво «CharData»). Це робить його взагалі простіше (і нешкідливим) завжди уникати цього.
bobince

19
Для тих, хто цікавиться h, псевдонім дляhtml_escape
lightswitch05

141

Оформити клас Ruby CGI . Існують методи кодування та декодування HTML, а також URL-адрес.

CGI::escapeHTML('Usage: foo "bar" <baz>')
# => "Usage: foo &quot;bar&quot; &lt;baz&gt;"

12
Дякую, це чудово, оскільки це можна зробити з контролерів. Не те, щоб я це зробив, звичайно.
Dan Rosenstark

2
Це корисно у функціональних / інтеграційних тестах для перевірки правильності вмісту, вставленого у шаблон (коли вміст повинен бути відхиленим HTML).
Alex D

Якщо вміст відображається на веб-сайті клієнта, крім вашого власного (де ви не можете контролювати перегляд), у чому проблема з уникненням HTML перед вставкою в базу даних? Чи є інша робота навколо?
n00b

Правильно - втеча перед входом до бази даних - це чудово. Ви просто хочете переконатися, що у вас там немає жодних старих невтікаючих хаків, перш ніж ви додали його ...
Кевін,

5
Мені більше подобається його синонім: CGI.escape_html
Liu

77

У Ruby on Rails 3 за замовчуванням буде вибрано HTML.

Для незахищених рядків використовуйте:

<%= raw "<p>hello world!</p>" %>

25

ERB :: Util.html_escape можна використовувати будь-де. Він доступний без використання requireв Rails.


це насправді використовується CGI.escapeHTMLвнизу
akostadinov

@akostadinov - однак результат інший. Наприклад, ERB :: Util.html_escape перетворить апострофи в & # x27; тоді як CGI :: escapeHTML не буде
Луї Сайерс

@LouisSayers, я не бачу, як це може статися: `` `[43] pry (main)> шоу-джерело ERB :: Util.html_escape Від: /usr/share/ruby/erb.rb @ рядок 945: власник : # <Клас: ERB :: Util> Видимість: public Кількість рядків: 3 def html_escape (s) CGI.escapeHTML (s.to_s) end `` `
akostadinov

@akostadinov - хм ... Просто знову побіг і так, вони дали такий же вихід. Я клянусь, що це дало різні результати, коли я запускав це на роботі (можливо, інша поведінка версії erb / cgi?). Мені доведеться побачити, чому я завтра отримав інший результат на роботі.
Луї Сайерс

17

Доповненням до відповіді Крістофера Бредфорда використовувати HTML, що втікає де завгодно, оскільки більшість людей сьогодні не використовують CGI, ви також можете використовувати Rack:

require 'rack/utils'
Rack::Utils.escape_html('Usage: foo "bar" <baz>')

Чи є кращий спосіб уникнути рядків подібним чином у методах екземплярів моделі?
Кодування активне

15

Ви можете використовувати будь-який h()або html_escape(), але більшість людей використовують h()за домовленістю. h()коротке для html_escape()рейок.

У вашому контролері:

@stuff = "<b>Hello World!</b>"

На ваш погляд:

<%=h @stuff %>

Якщо ви переглядаєте джерело HTML: ви побачите вихідні дані, фактично не змащуючи дані. Тобто це закодовано як &lt;b&gt;Hello World!&lt;/b&gt;.

З'явиться, що відображається як <b>Hello World!</b>


9

Порівняння різних методів:

> CGI::escapeHTML("quote ' double quotes \"")
=> "quote &#39; double quotes &quot;"

> Rack::Utils.escape_html("quote ' double quotes \"")
=> "quote &#x27; double quotes &quot;"

> ERB::Util.html_escape("quote ' double quotes \"")
=> "quote &#39; double quotes &quot;"

Я написав своє, щоб бути сумісним із втечею Rails ActiveMailer:

def escape_html(str)
  CGI.escapeHTML(str).gsub("&#39;", "'")
end

0

h() також корисний для уникнення цитат.

Наприклад, у мене є вид, який генерує посилання за допомогою текстового поля result[r].thtitle. Текст може містити поодинокі цитати. Якщо я не уникнув result[r].thtitleметоду підтвердження, Javascript буде порушений:

&lt;%= link_to_remote "#{result[r].thtitle}", :url=>{ :controller=>:resource,
:action         =>:delete_resourced,
:id     => result[r].id,
:th     => thread,                                                                                                      
:html       =>{:title=> "<= Remove"},                                                       
:confirm    => h("#{result[r].thtitle} will be removed"),                                                   
:method     => :delete %>

&lt;a href="#" onclick="if (confirm('docs: add column &amp;apos;dummy&amp;apos; will be removed')) { new Ajax.Request('/resource/delete_resourced/837?owner=386&amp;th=511', {asynchronous:true, evalScripts:true, method:'delete', parameters:'authenticity_token=' + encodeURIComponent('ou812')}); }; return false;" title="&lt;= Remove">docs: add column 'dummy'</a>

Примітка: :htmlRails за допомогою магічної декларації заголовок уникає.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.