Ruby on Rails: Wie rendere ich einen String als HTML?


154

ich habe

@str = "<b>Hi</b>"

und aus meiner erb sicht:

<%= @str %>

Was auf der Seite angezeigt wird, ist: <b>Hi</b>Wenn ich wirklich Hallo will . Was ist der rubinrote Weg, um einen String als HTML-Markup zu "interpretieren"?


Bearbeiten : der Fall wo

@str = "<span class=\"classname\">hello</span>"

Wenn ich es aus meiner Sicht tue

<%raw @str %>

Der HTML-Quellcode ist <span class=\"classname\">hello</span> wo ich wirklich will <span class="classname">hello</span>(ohne die Backslashes, die den doppelten Anführungszeichen entgangen sind). Was ist der beste Weg, um diese doppelten Anführungszeichen zu "entkommen"?


Sie können auch die% Q [] -Syntax für die Escape-Zeichenfolge verwenden. zB %Q["quotation marks"] => "\"quotation marks\"" Quelle: en.wikibooks.org/wiki/Ruby_Programming/Syntax/… Weiß nicht, ob das hilft.
0112

Antworten:


328

AKTUALISIEREN

Aus Sicherheitsgründen wird empfohlen, sanitizeanstelle von zu verwenden html_safe. Verknüpfung


Was passiert, ist, dass Rails aus Sicherheitsgründen Ihrer Zeichenfolge entgeht, da möglicherweise schädlicher Code darin eingebettet ist. Wenn Sie Rails jedoch mitteilen, dass es sich um eine Zeichenfolge handelt html_safe, wird diese direkt durchlaufen.

@str = "<b>Hi</b>".html_safe
<%= @str %>

ODER

@str = "<b>Hi</b>"
<%= @str.html_safe %>

Die Verwendung rawfunktioniert einwandfrei, aber alles, was es tut, ist, die Zeichenfolge in eine Zeichenfolge zu konvertieren und dann html_safe aufzurufen. Wenn ich weiß, dass ich eine Zeichenfolge habe, rufe ich lieber html_safe direkt auf, da dadurch ein unnötiger Schritt übersprungen wird und klarer wird, was los ist. Details zum Escape-Escape und zum XSS-Schutz finden Sie in diesem Asciicast .


Fantastisch. Ich konnte nicht finden, wie ich das machen sollte, selbst nachdem ich eine Stunde lang gesucht hatte. Danke für deine Antwort.
Salil

1
Ich habe immer benutzt raw. Sehr froh darüber zu wissen!
jmcharnes

Hanks aus der Zukunft geben =)
Carlos Morales


16

Verwenden Sie roh :

<%=raw @str >

Aber wie @ jmort253 richtig sagt, überlegen Sie, wo der HTML-Code wirklich hingehört.


Hallo, diese Lösung funktioniert, außer mit einer Einschränkung: siehe bearbeitete Frage
Tim

14

Wenn Sie auf sind railsdie nutzt erubis - die coolste Art , es zu tun ist ,

<%== @str >

Beachten Sie das doppelte Gleichheitszeichen. Weitere Informationen finden Sie in der entsprechenden Frage zu SO.



7

Sie mischen Ihre Geschäftslogik mit Ihren Inhalten. Stattdessen würde ich empfehlen, die Daten an Ihre Seite zu senden und dann etwas wie JQuery zu verwenden, um die Daten dort zu platzieren, wo Sie sie benötigen.

Dies hat den Vorteil, dass Ihr gesamtes HTML auf den HTML-Seiten verbleibt, zu denen es gehört, sodass Ihre Webdesigner das HTML später ändern können, ohne den serverseitigen Code durchgehen zu müssen.

Wenn Sie kein JavaScript verwenden möchten, können Sie Folgendes versuchen:

@str = "Hi"

<b><%= @str ></b>

Zumindest auf diese Weise befindet sich Ihr HTML auf der HTML-Seite, zu der es gehört.


Das Problem ist, dass meine App eine schlecht markierte Datei aufnimmt und sie über reguläre Ausdrücke in ein gutes HTML-Markup "übersetzt", um sie an die Ansicht zu senden. Daher ist das HTML-Markup, das generiert wird, dynamisch, sodass ich nicht a priori wissen kann, welche Tags @str umgeben sollen. Wo würde ich diese "Übersetzungsarbeit" durchführen, wenn nicht in den Modellen? Ich dachte, wir sollten keinen umfangreichen Logikcode in den Ansichten haben.
Tim

1
Es ist wirklich eine Ansichtssache. Bei der Entwicklung einer neuen App halte ich lieber alles so sauber wie möglich. Aber oft müssen wir im Rahmen dessen arbeiten, was andere uns hinterlassen haben. Wenn Ihre Datenquelle HTML-Markup zurückgibt, sehen Sie sich möglicherweise die Verwendung von "raw" an, wie in der Lösung von Michael Stum beschrieben.
jmort253

1
Wenn Sie die Unterstützung eines Codes geerbt haben und der Code Bereiche aufweist, die schlechtes Denken oder Design aufweisen, liegt es in Ihrer Verantwortung, ihn zu bereinigen, um ihn wartbarer zu machen. Wenn Sie es so lassen, wie Sie es gefunden haben, ist es in Ordnung, wenn es von Anfang an großartiger Code ist, aber es besser zu belassen, als Sie es gefunden haben, ist gut, wenn es Arbeit benötigt. Ein Teil meiner Arbeit besteht darin, einige ältere Apps zu verwalten. Ich bin ein Fan davon, Dinge nicht zu reparieren, die nicht kaputt sind, aber sie konnten aufgrund ihrer Schreibweise nicht einfach verbessert werden. Ich musste die meisten Funktionsaufrufe neu schreiben, aber es ist jetzt so viel einfacher, damit zu arbeiten.
der Blechmann

Sie sollten kein JavaScript für Ihre HTML-Interpolation verwenden, wenn es keinen anderen Grund gibt, JS zu verwenden. Dadurch wird Ihre Website für Nicht-JS-Browser beschädigt (ja, es gibt einige).
Marnen Laibow-Koser

1
Natürlich liegt es an Ihnen, sicherzustellen, dass nicht bösartiges Markup sichergestellt wird, wenn Sie nicht entkommene Inhalte zulassen.
Macario

6

Oder Sie können die CGI.unescapeHTML- Methode ausprobieren .

CGI.unescapeHTML "&lt;p&gt;This is a Paragraph.&lt;/p&gt;"
=> "<p>This is a Paragraph.</p>"

0

Da Sie übersetzen und Ihren gewünschten Code aus der beschissenen codierten Datei einer Person auswählen, können Sie content_tag in Kombination mit Ihren regulären Ausdrücken verwenden.

Wenn Sie aus den API-Dokumenten stehlen, können Sie diesen übersetzten Code content_tagwie folgt interpolieren :

<%= content_tag translated_tag_type.to_sym, :class => "#{translated_class}" do -%>
<%= translated_text %>
<% end -%>
# => <div class="strong">Hello world!</div>

Wenn Sie Ihren Code nicht kennen, wird durch diese Art des Denkens sichergestellt, dass Ihr übersetzter Code zu konform ist.


Ich gehe davon aus, dass translate_text der eigentliche Inhalt innerhalb des div ist, oder? dh im Beispiel wäre es "Hallo Welt!"? Was ist, wenn translated_text mehr HTML enthält, dh verschachtelte Divs oder Spans? Muss ich dann mehrmals content_tag aufrufen?
Tim

und ... Entschuldigung, drücken Sie früh die Eingabetaste ... jedes verschachtelte div / span darin ist immer noch ein content_tag und Sie müssen es trotzdem validieren, oder? Da wir nicht sehen können, was Sie mit Ihrer ausgefallenen Übersetzung machen ;-), würde ich davon ausgehen, dass Sie nach ALLEN Tags suchen, unabhängig davon, ob sich der reguläre Ausdruck auf dem 'übergeordneten' Element des HTML befindet ... wie z. B. <ul>. du würdest nicht alle li's als dicke arschschnur zum drucken bringen, oder? Jeder wäre sein eigener content_tag: li, Text korrekt?
pjammer

0

@str = "<span class=\"classname\">hello</span>" Wenn ich es aus meiner Sicht tue

<%raw @str %> Der HTML-Quellcode ist <span class=\"classname\">hello</span>genau das, was ich wirklich möchte <span class="classname">hello</span>(ohne die Backslashes, die den doppelten Anführungszeichen entgangen sind). Was ist der beste Weg, um diese doppelten Anführungszeichen zu "entkommen"?

Lösung: Verwenden Sie doppelte Anführungszeichen in einfachen Anführungszeichen (oder einfache Anführungszeichen in doppelten Anführungszeichen), um zu vermeiden, dass ein Backslash auftritt.

@str = '<span class="classname">hello</span>'
<%raw @str %>

0

Die html_safe-Version funktioniert gut in Rails 4 ...

<%= "<center style=\"color: green; font-size: 1.1em\" > Administrators only </center>".html_safe if current_user.admin? %
>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.