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.