Ruby on Rails: bagaimana cara membuat string sebagai HTML?

154

saya sudah

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

dan dalam tampilan erb saya:

<%= @str %>

Apa yang akan ditampilkan pada halaman adalah: <b>Hi</b>ketika apa yang saya inginkan adalah Hai . Apa cara ruby ​​untuk "menafsirkan" string sebagai markup HTML?


Edit : kasus di mana

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

Jika menurut saya saya lakukan

<%raw @str %>

Kode sumber HTML adalah <span class=\"classname\">hello</span> tempat yang saya inginkan <span class="classname">hello</span>(tanpa backslash yang lolos dari tanda kutip ganda). Apa cara terbaik untuk "menghapus" tanda kutip ganda itu?

Tim
sumber
Anda mungkin juga mempertimbangkan untuk menggunakan sintaks% Q [] untuk melarikan diri string. mis. %Q["quotation marks"] => "\"quotation marks\"" Sumber: en.wikibooks.org/wiki/Ruby_Programming/Syntax/… Tidak tahu apakah itu membantu.
0112

Jawaban:

328

MEMPERBARUI

Untuk alasan keamanan, disarankan untuk menggunakan sanitizebukan html_safe. Tautan


Apa yang terjadi adalah bahwa, sebagai langkah keamanan, Rails keluar dari string Anda untuk Anda karena mungkin ada kode jahat yang tertanam di dalamnya. Tetapi jika Anda memberi tahu Rails bahwa string Anda adalah html_safe, itu akan melewatinya.

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

ATAU

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

Menggunakan rawberfungsi dengan baik, tetapi semua yang dilakukannya adalah mengubah string ke string, dan kemudian memanggil html_safe. Ketika saya tahu saya memiliki string, saya lebih suka memanggil html_safe secara langsung, karena melewatkan langkah yang tidak perlu dan membuatnya lebih jelas apa yang terjadi. Rincian tentang pelarian string dan perlindungan XSS ada di Asciicast ini .

Yakub
sumber
Fantastis. Saya tidak dapat menemukan cara melakukannya bahkan setelah mencari selama satu jam. Terima kasih atas jawaban anda.
Salil
1
Saya selalu menggunakan raw. Sangat senang mengetahui hal ini!
jmcharnes
Memberi banyak terima kasih dari masa depan =)
Carlos Morales
1
sanitize dihapus menurut stackoverflow.com/questions/44575106/…
Youness
16

Gunakan mentah :

<%=raw @str >

Tetapi seperti yang dikatakan @ jmort253 dengan benar, pertimbangkan di mana letak HTML yang sebenarnya.

Michael Stum
sumber
Hai, solusi ini berfungsi, kecuali dengan satu peringatan: silakan lihat pertanyaan yang diedit
Tim
14

Jika Anda railsmenggunakan Erubis - cara paling keren untuk melakukannya adalah

<%== @str >

Perhatikan tanda sama dengan dobel. Lihat pertanyaan terkait pada SO untuk info lebih lanjut.

jibiel
sumber
7

Anda mencampur logika bisnis Anda dengan konten Anda. Sebagai gantinya, saya akan merekomendasikan mengirim data ke halaman Anda dan kemudian menggunakan sesuatu seperti JQuery untuk menempatkan data ke tempat yang Anda butuhkan.

Ini memiliki keuntungan menjaga semua HTML Anda di halaman HTML di tempatnya sehingga desainer web Anda dapat memodifikasi HTML nanti tanpa harus menuangkan melalui kode sisi server.

Atau jika Anda tidak ingin menggunakan JavaScript, Anda dapat mencoba ini:

@str = "Hi"

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

Setidaknya dengan cara ini HTML Anda ada di halaman HTML tempatnya.

jmort253
sumber
Masalahnya adalah, aplikasi saya mengambil file yang ditandai dengan buruk, dan "menerjemahkannya" melalui regex ke markup HTML yang baik untuk dikirim ke tampilan. Oleh karena itu, markup HTML yang dihasilkan adalah dinamis, jadi saya tidak dapat mengetahui apriori tag mana yang seharusnya mengelilingi @str. Di mana saya akan melakukan pekerjaan "terjemahan" ini, jika tidak dalam model? Saya pikir kami tidak seharusnya memiliki kode logika yang luas dalam pandangan.
Tim
1
Ini benar-benar masalah pendapat. Saat mengembangkan aplikasi baru, saya lebih memilih untuk menjaga semuanya sebersih mungkin. Tetapi seringkali kita harus bekerja dalam batasan dari apa yang orang lain tinggalkan pada kita. Jika sumber data Anda mengembalikan markup HTML maka mungkin lihat menggunakan "mentah" seperti yang dijelaskan dalam solusi Michael Stum.
jmort253
1
Jika Anda telah mewarisi dukungan beberapa kode, dan kode tersebut memiliki area yang menunjukkan pemikiran atau desain yang buruk, maka itu benar-benar merupakan bagian dari tanggung jawab Anda untuk membersihkannya agar lebih mudah dikelola. Membiarkannya seperti yang Anda temukan itu baik-baik saja ketika itu kode yang bagus untuk memulai, tetapi meninggalkannya lebih baik daripada Anda menemukan itu baik ketika dibutuhkan kerja. Bagian dari pekerjaan saya adalah mengelola beberapa aplikasi lawas; Saya penggemar tidak memperbaiki hal-hal yang tidak rusak, tetapi mereka tidak dapat ditingkatkan dengan mudah karena cara mereka ditulis. Saya harus menulis ulang sebagian besar panggilan fungsi tetapi jauh lebih mudah untuk bekerja dengan sekarang.
the Tin Man
Anda seharusnya tidak menggunakan JavaScript untuk interpolasi HTML Anda jika tidak ada alasan lain untuk menggunakan JS. Itu akan merusak situs Anda untuk non-JS browser (ya, ada yang beberapa).
Marnen Laibow-Koser
1
Tentu saja jika Anda mengizinkan konten yang tidak diloloskan, tanggung jawab memastikan markup non jahat terserah Anda.
Macario
6

Atau Anda dapat mencoba metode CGI.unescapeHTML .

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

karena Anda menerjemahkan, dan memilih kode yang Anda inginkan dari file kode jelek seseorang, dapatkah Anda menggunakan content_tag, dalam kombo dengan regex Anda.

Mencuri dari api docs, Anda dapat menginterpolasi kode yang diterjemahkan ini menjadi content_tagseperti:

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

Tidak mengetahui kode Anda, pemikiran semacam ini akan memastikan kode terjemahan Anda terlalu sesuai.

pamammer
sumber
Saya berasumsi terjemahan adalah konten aktual dalam div, kan? yaitu, dalam contoh, itu akan menjadi "Halo dunia!"? Bagaimana jika translation_text memiliki lebih banyak HTML di dalamnya, yaitu div bersarang atau rentang? Apakah saya harus memanggil content_tag berkali-kali?
Tim
dan ... maaf tekan enter awal ... setiap div bersarang / span di dalam masih content_tag dan Anda masih perlu memvalidasi itu kan? Karena kami tidak dapat melihat apa yang Anda lakukan dengan terjemahan mewah Anda ;-), saya anggap Anda mencari SEMUA tag, terlepas dari apakah regex ada di 'induk' dari html ... seperti <ul>. Anda tidak akan menempatkan semua li sebagai string pantat besar untuk dicetak kan? masing-masing akan menjadi content_tag sendiri: li, teks yang benar?
pjammer
0

@str = "<span class=\"classname\">hello</span>" Jika menurut saya saya lakukan

<%raw @str %> Kode sumber HTML adalah <span class=\"classname\">hello</span>tempat yang benar-benar saya inginkan <span class="classname">hello</span>(tanpa garis miring terbalik> tanda kutip ganda). Apa cara terbaik untuk "menghapus" tanda kutip ganda itu?

Solusi: gunakan tanda kutip ganda di dalam tanda kutip tunggal (atau selembar tunggal dalam ganda) untuk menghindari melarikan diri dengan backslash.

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

Versi html_safe berfungsi dengan baik di Rails 4 ...

<%= "<center style=\"color: green; font-size: 1.1em\" > Administrators only </center>".html_safe if current_user.admin? %
>
GA
sumber