mentah vs html_safe vs. h untuk menghapus html

323

Misalkan saya memiliki string berikut

@x = "<a href='#'>Turn me into a link</a>"

Dalam pandangan saya, saya ingin tautan ditampilkan. Yaitu, saya tidak ingin semua yang ada di @x tidak terhapus dan ditampilkan sebagai string. Apa perbedaan antara menggunakan

<%= raw @x %>
<%= h @x %>
<%= @x.html_safe %>

?

grautur
sumber
Karena tidak ada yang menyebutkannya, saya pikir saya juga akan menyebutkan ada <%== @x %>yang merupakan alias untuk <%= raw(@x) %> edgeguides.rubyonrails.org/…
CTS_AE

Jawaban:

386

Mengingat Rel 3:

html_safesebenarnya "set the string" sebagai HTML Safe (ini sedikit lebih rumit dari itu, tetapi pada dasarnya itu). Dengan cara ini, Anda dapat mengembalikan string HTML Safe dari helper atau model sesuka hati.

hhanya dapat digunakan dari dalam controller atau view, karena itu dari helper. Itu akan memaksa output untuk keluar. Itu tidak benar-benar usang, tetapi Anda kemungkinan besar tidak akan menggunakannya lagi: satu-satunya penggunaan adalah untuk "mengembalikan" html_safedeklarasi, sangat tidak biasa.

Menempatkan ekspresi Anda dengan rawsebenarnya sama dengan memanggil to_sdirantai html_safedengannya, tetapi dideklarasikan pada helper, sama seperti h, jadi itu hanya dapat digunakan pada pengontrol dan tampilan.

" SafeBuffers and Rails 3.0 " adalah penjelasan yang bagus tentang bagaimana SafeBuffers (kelas yang melakukan html_safesihir) bekerja.

Fábio Batista
sumber
42
Saya tidak akan mengatakan itu hakan ditinggalkan. Penggunaannya "Hi<br/>#{h@ user.name}".html_safecukup umum dan penggunaannya diterima.
Maletor
1
@Metetor penggunaan yang menarik, meskipun saya masih berpikir itu termasuk dalam kategori "tidak biasa".
Fábio Batista
5
String # html_safe sebenarnya mengembalikan instance ActiveSupport :: SafeBuffer yang membungkus string asli dan apakah #html_safe? . String asli tidak menjadi #html_safe? setelah memanggil #html_safe di atasnya.
jmaxyz
9
Perhatikan bahwa ada perbedaan halus antara rawdan html_safedalam praktiknya: raw(nil)mengembalikan string kosong, sambil nil.html_safemelempar pengecualian.
Van der Hoorn
2
htidak akan "mengembalikan" deklarasi html_safe. Ketika sebuah string html_safe, htidak akan melakukan apa pun.
GuiGS
113

Saya pikir itu diulang: html_safetidak tidak HTML-melarikan diri string Anda. Bahkan, itu akan mencegah string Anda lolos.

<%= "<script>alert('Hello!')</script>" %>

akan menempatkan:

&lt;script&gt;alert(&#x27;Hello!&#x27;)&lt;/script&gt;

ke sumber HTML Anda (yay, sangat aman!), sementara:

<%= "<script>alert('Hello!')</script>".html_safe %>

akan memunculkan dialog peringatan (apakah Anda yakin itu yang Anda inginkan?). Jadi, Anda mungkin tidak ingin memanggil html_safestring yang dimasukkan pengguna.

roasm
sumber
81
Dengan kata lain, html_safe bukan "tolong buat html ini aman", itu sebaliknya - Anda adalah programmer yang memberi tahu rails bahwa "string ini aman html, janji!"
PaulMurrayCbr
sebenarnya saya datang ke sini untuk mencari tahu apakah itu benar-benar unescape atau hanya membuat tanda bahwa tidak perlu to_escape . Cukup berbeda. Oh well, pergilah untuk membaca kode sumbernya.
Simon B.
Konsep "html_safe" hanyalah bendera meta pada string. Menandai sesuatu yang html_safetidak tidak melarikan diri atau unescape. Sementara hasil akhir dari menandai sesuatu sebagai bukan HTML aman, dan kemudian menggunakan pelepasan ERB <% = tag secara implisit, mungkin sama dengan menghapus data dan kemudian kembali melarikannya pada output, secara fungsional tidak melakukan keduanya. Jenis suka perbedaan (6 * -1 * -1), vs 6.
Ben Zittlau
46

Perbedaannya adalah antara Rails html_safe()dan raw(). Ada sebuah pos yang sangat bagus oleh Yehuda Katz tentang ini, dan itu benar-benar bermuara pada ini:

def raw(stringish)

  stringish.to_s.html_safe

end

Ya, raw()adalah pembungkus html_safe()yang memaksa input ke String dan kemudian memanggilnya html_safe(). Ini juga merupakan kasus yang raw()merupakan penolong dalam modul sedangkan html_safe()merupakan metode pada kelas String yang membuat contoh ActiveSupport :: SafeBuffer baru - yang memiliki @dirtytanda di dalamnya.

Lihat " Rails 'html_safe vs. raw ".

Pankhuri
sumber
30
  1. html_safe :

    Menandai string sebagai brankas tepercaya. Ini akan dimasukkan ke dalam HTML tanpa pelolosan tambahan dilakukan.

    "<a>Hello</a>".html_safe
    #=> "<a>Hello</a>"
    
    nil.html_safe
    #=> NoMethodError: undefined method `html_safe' for nil:NilClass
  2. raw :

    rawhanyalah pembungkus di sekitar html_safe. Gunakan rawjika ada kemungkinan string akan muncul nil.

    raw("<a>Hello</a>")
    #=> "<a>Hello</a>"
    
    raw(nil)
    #=> ""
  3. halias untuk html_escape:

    Metode utilitas untuk keluar dari karakter tag HTML. Gunakan metode ini untuk menghindari konten yang tidak aman.

    Di Rails 3 dan di atasnya digunakan secara default sehingga Anda tidak perlu menggunakan metode ini secara eksplisit

Deepak Mahakale
sumber
14

Cara aman terbaik adalah: <%= sanitize @x %>

Itu akan menghindari XSS!

Guilherme Y. Hatano
sumber
2

Dalam istilah Simple Rails:

h hapus tag html menjadi karakter angka sehingga rendering tidak akan merusak html Anda

html_safe menetapkan boolean dalam string sehingga string tersebut dianggap sebagai html save

raw Itu dikonversi ke html_safe ke string

pengguna3118220
sumber
his html_safe, yang berarti HTML diterjemahkan apa adanya.
Dave Newton
Jawabannya benar: h adalah html_escape ... dari basis kode Rails
notapatch