Ruby on Rails: come rendere una stringa come HTML?


154

io ho

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

e nella mia vista erb:

<%= @str %>

Quello che verrà visualizzato nella pagina è: <b>Hi</b>quando quello che voglio davvero è Ciao . Qual è il modo rubino di "interpretare" una stringa come markup HTML?


Modifica : il caso in cui

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

Se a mio avviso lo faccio

<%raw @str %>

Il codice sorgente HTML è <span class=\"classname\">hello</span> dove quello che voglio veramente è <span class="classname">hello</span>(senza le barre rovesciate che sfuggivano alle doppie virgolette). Qual è il modo migliore per "liberare" quelle doppie virgolette?


Si potrebbe anche considerare l'utilizzo della sintassi% Q [] per l'escaping della stringa. ad es. %Q["quotation marks"] => "\"quotation marks\"" Fonte: en.wikibooks.org/wiki/Ruby_Programming/Syntax/… Non so se questo aiuta.
0112

Risposte:


328

AGGIORNARE

Per motivi di sicurezza, si consiglia di utilizzare sanitizeanziché html_safe. collegamento


Quello che sta accadendo è che, come misura di sicurezza, Rails sta sfuggendo alla tua stringa perché potrebbe contenere codice dannoso. Ma se dici a Rails che la tua stringa è html_safe, la passerà attraverso.

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

O

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

L'utilizzo rawfunziona correttamente, ma tutto ciò che sta facendo è convertire la stringa in una stringa e quindi chiamare html_safe. Quando so di avere una stringa, preferisco chiamare direttamente html_safe, perché salta un passaggio non necessario e rende più chiaro cosa sta succedendo. I dettagli sull'escaping delle stringhe e sulla protezione XSS si trovano in questo Asciicast .


Fantastico. Non sono riuscito a trovare il modo di farlo nemmeno dopo aver cercato per un'ora. Grazie per la tua risposta.
Salil,

1
L'ho sempre usato raw. Molto felice di saperlo!
jmcharnes,

Dare matasse dal futuro =)
Carlos Morales il

1
sanitize viene rimosso secondo stackoverflow.com/questions/44575106/…
Youness

16

Usa crudo :

<%=raw @str >

Ma come dice correttamente @ jmort253, considera dove appartiene veramente l'HTML.


Ciao, questa soluzione funziona, tranne con un avvertimento: vedi la domanda modificata
Tim

14

Se sei su quello railsche utilizza Erubis , il modo migliore per farlo è

<%== @str >

Nota il doppio segno di uguale. Vedere la domanda correlata su SO per ulteriori informazioni.



7

Stai mescolando la tua logica aziendale con i tuoi contenuti. Invece, ti consiglio di inviare i dati alla tua pagina e di utilizzare qualcosa come JQuery per posizionare i dati dove ti servono.

Questo ha il vantaggio di mantenere tutto il tuo HTML nelle pagine HTML a cui appartiene in modo che i tuoi web designer possano modificare il codice HTML in un secondo momento senza dover passare attraverso il codice lato server.

Oppure, se non desideri utilizzare JavaScript, puoi provare questo:

@str = "Hi"

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

Almeno in questo modo il tuo HTML si trova nella pagina HTML a cui appartiene.


Il problema è che la mia app sta rilevando un file scarsamente marcato e "traducendolo" tramite regex in un buon markup HTML da inviare alla vista. Pertanto, il markup HTML che viene generato è dinamico, quindi non posso sapere a priori quali tag dovrebbero circondare @str. Dove eseguirò questo lavoro di "traduzione", se non nei modelli? Pensavo che non avessimo dovuto avere un ampio codice logico nelle viste.
Tim

1
È davvero una questione di opinione. Quando sviluppo un'app nuova preferisco mantenere tutto il più pulito possibile. Ma spesso dobbiamo lavorare entro i limiti di ciò che gli altri ci hanno lasciato. Se l'origine dati restituisce markup HTML, forse dai un'occhiata all'utilizzo di "raw" come descritto nella soluzione di Michael Stum.
jmort253,

1
Se hai ereditato il supporto di alcuni codici e il codice ha aree che mostrano cattive idee o design, allora è davvero una tua responsabilità ripulirlo per renderlo più gestibile. Lasciarlo come hai trovato va bene quando è un ottimo codice per cominciare, ma lasciarlo meglio di come lo hai trovato va bene quando ha bisogno di lavoro. Parte del mio lavoro è gestire alcune app legacy; Sono un fan del non aggiustare cose che non si rompono, ma non possono essere migliorate facilmente a causa del modo in cui sono state scritte. Ho dovuto riscrivere la maggior parte delle chiamate di funzione, ma è molto più facile lavorare con ora.
Tin Man,

Non dovresti usare JavaScript per la tua interpolazione HTML se non ci sono altri motivi per usare JS. Ciò interromperà il tuo sito per i browser non JS (sì, ce ne sono alcuni).
Marnen Laibow-Koser,

1
Ovviamente, se consenti contenuti non salvati, la responsabilità di garantire il markup non male dipende da te.
Macario,

6

Oppure puoi provare il metodo CGI.unescapeHTML .

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

0

dal momento che stai traducendo e scegliendo il tuo codice desiderato dal file codificato di una persona, potresti usare content_tag, in combinazione con il tuo regex.

Rubando dai documenti API, potresti interpolare questo codice tradotto in un content_tagsimile:

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

Non conoscendo il tuo codice, questo tipo di pensiero farà in modo che il tuo codice tradotto sia troppo conforme.


Sto assumendo translate_text è il contenuto reale all'interno del div, giusto? vale a dire, nell'esempio, sarebbe "Ciao mondo!"? Che cosa succede se translate_text ha più HTML, ovvero div o span nidificati? Dovrei chiamare content_tag molte volte allora?
Tim

e ... scusa premi entra presto ... ogni div / span nidificato all'interno è ancora un content_tag e devi comunque convalidarlo, giusto? Dal momento che non possiamo vedere cosa stai facendo con la tua fantasia di traduzione ;-), presumo che cerchi TUTTI i tag, indipendentemente dal fatto che regex sia sul 'genitore' dell'html ... come <ul>. non metteresti tutte le li come una grande stringa da stampare, vero? ognuno sarebbe il proprio content_tag: li, testo corretto?
Pjammer,

0

@str = "<span class=\"classname\">hello</span>" Se a mio avviso lo faccio

<%raw @str %> Il codice sorgente HTML è <span class=\"classname\">hello</span>dove voglio davvero <span class="classname">hello</span>(senza le barre rovesciate che sfuggivano alle doppie> virgolette). Qual è il modo migliore per "liberare" quelle doppie virgolette?

Soluzione: utilizzare virgolette doppie all'interno di virgolette singole (o singole all'interno di doppie) per evitare la fuga con una barra rovesciata.

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

0

La versione html_safe funziona bene in Rails 4 ...

<%= "<center style=\"color: green; font-size: 1.1em\" > Administrators only </center>".html_safe if current_user.admin? %
>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.