Ruby on Rails: làm thế nào để kết xuất một chuỗi dưới dạng HTML?


154

Tôi có

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

và trong quan điểm erb của tôi:

<%= @str %>

Những gì sẽ hiển thị trên trang là: <b>Hi</b>khi điều tôi thực sự muốn là Hi . Cách ruby ​​để "diễn giải" một chuỗi như đánh dấu HTML là gì?


Chỉnh sửa : trường hợp

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

Nếu theo quan điểm của tôi, tôi làm

<%raw @str %>

Mã nguồn HTML là <span class=\"classname\">hello</span> nơi tôi thực sự muốn <span class="classname">hello</span>(không có dấu gạch chéo ngược thoát khỏi dấu ngoặc kép). Cách tốt nhất để "unescape" những trích dẫn kép đó là gì?


Bạn cũng có thể cân nhắc sử dụng cú pháp% Q [] để thoát chuỗi. ví dụ %Q["quotation marks"] => "\"quotation marks\"" Nguồn: en.wikibooks.org/wiki/Ruby_Programming/Syntax/ Đổi Đừng biết nếu điều đó có ích.
0112

Câu trả lời:


328

CẬP NHẬT

Vì lý do bảo mật, nên sử dụng sanitizethay vì html_safe. Liên kết


Điều đang xảy ra là, như một biện pháp bảo mật, Rails đang thoát khỏi chuỗi của bạn cho bạn bởi vì nó có thể có mã độc được nhúng trong đó. Nhưng nếu bạn nói với Rails rằng chuỗi của bạn là html_safe, chuỗi đó sẽ chuyển qua ngay.

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

HOẶC LÀ

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

Sử dụng rawhoạt động tốt, nhưng tất cả những gì nó làm là chuyển đổi chuỗi thành chuỗi, sau đó gọi html_safe. Khi tôi biết tôi có một chuỗi, tôi thích gọi trực tiếp html_safe, vì nó bỏ qua một bước không cần thiết và làm cho nó rõ ràng hơn những gì đang diễn ra. Chi tiết về thoát chuỗi và bảo vệ XSS có trong Asciicast này .


Tuyệt diệu. Tôi không thể tìm thấy làm thế nào để làm điều đó ngay cả sau khi tìm kiếm trong một giờ. Cảm ơn câu trả lời của bạn.
Salil

1
Tôi đã luôn luôn sử dụng raw. Rất vui mừng khi biết về điều này!
jmcharnes

Đưa ra những vị trí từ tương lai =)
Carlos Morales

1
vệ sinh được xóa theo stackoverflow.com/questions/44575106/NH
Youness

16

Sử dụng thô :

<%=raw @str >

Nhưng như @ jmort253 nói chính xác, hãy xem xét nơi HTML thực sự thuộc về.


Xin chào, giải pháp này hoạt động, ngoại trừ với một cảnh báo: vui lòng xem câu hỏi đã được chỉnh sửa
Tim

14

Nếu bạn đang railssử dụng Erubis - cách tuyệt vời nhất để làm điều đó là

<%== @str >

Lưu ý dấu bằng đôi. Xem câu hỏi liên quan trên SO để biết thêm.



7

Bạn đang trộn logic kinh doanh của bạn với nội dung của bạn. Thay vào đó, tôi khuyên bạn nên gửi dữ liệu đến trang của mình và sau đó sử dụng một cái gì đó như JQuery để đặt dữ liệu mà bạn cần đến.

Điều này có lợi thế là giữ tất cả HTML của bạn trong các trang HTML nơi nó thuộc về để các nhà thiết kế web của bạn có thể sửa đổi HTML sau này mà không phải đổ mã bên máy chủ.

Hoặc nếu bạn không muốn sử dụng JavaScript, bạn có thể thử điều này:

@str = "Hi"

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

Ít nhất theo cách này, HTML của bạn nằm trong trang HTML nơi nó thuộc về.


Vấn đề là, ứng dụng của tôi đang lấy một tệp bị đánh dấu kém và "dịch" nó qua các biểu thức chính tả sang đánh dấu HTML tốt để gửi đến chế độ xem. Do đó, đánh dấu HTML đang được tạo là động, vì vậy tôi không thể biết một tiên nghiệm mà các thẻ được cho là bao quanh @str. Tôi sẽ thực hiện công việc "dịch" này ở đâu, nếu không có trong các mô hình? Tôi nghĩ rằng chúng ta không nên có mã logic rộng rãi trong các khung nhìn.
Tim

1
Đó thực sự là một vấn đề quan điểm. Khi phát triển một ứng dụng mới, tôi thích giữ mọi thứ sạch nhất có thể. Nhưng đôi khi chúng ta phải làm việc trong giới hạn của những gì người khác đã để lại cho chúng ta. Nếu nguồn dữ liệu của bạn trả về đánh dấu HTML thì có lẽ hãy xem sử dụng "thô" như được mô tả trong giải pháp của Michael Stum.
jmort253

1
Nếu bạn được thừa hưởng sự hỗ trợ của một số mã và mã có các khu vực thể hiện tư duy hoặc thiết kế kém, thì đó thực sự là một phần trách nhiệm của bạn trong việc làm sạch nó để làm cho nó dễ bảo trì hơn. Để lại nó như bạn thấy nó vẫn ổn khi bắt đầu với mã tuyệt vời, nhưng để nó tốt hơn bạn thấy nó là tốt khi nó cần làm việc. Một phần công việc của tôi là quản lý một số ứng dụng cũ; Tôi là một fan hâm mộ của việc không sửa chữa những thứ không bị hỏng, nhưng chúng không thể được tăng cường dễ dàng vì cách chúng được viết. Tôi đã phải viết lại hầu hết các lệnh gọi hàm nhưng bây giờ nó dễ làm việc hơn nhiều.
Tin Man

Bạn không nên sử dụng JavaScript cho phép nội suy HTML của mình nếu không có lý do nào khác để sử dụng JS. Điều đó sẽ phá vỡ trang web của bạn cho các trình duyệt không JS (có, có một số).
Marnen Laibow-Koser

1
Dĩ nhiên nếu bạn cho phép nội dung không thoát được thì việc bảo đảm đánh dấu không xấu tùy thuộc vào bạn.
Macario

6

Hoặc bạn có thể thử phương pháp CGI.unescapeHTML .

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

0

vì bạn đang dịch và chọn mã mong muốn từ tệp được mã hóa nhảm nhí của một người, bạn có thể sử dụng content_tag, kết hợp với biểu thức chính quy của bạn không.

Ăn cắp từ các tài liệu api, bạn có thể nội suy mã dịch này thành một content_tagdạng như sau:

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

Không biết mã của bạn, kiểu suy nghĩ này sẽ đảm bảo mã dịch của bạn quá tuân thủ.


Tôi đang giả sử dịch bản dịch là nội dung thực tế trong div, phải không? tức là trong ví dụ, nó sẽ là "Xin chào thế giới!"? Điều gì sẽ xảy ra nếu dịch bản dịch có nhiều HTML hơn trong đó, tức là các div hoặc sp lồng nhau? Tôi có phải gọi content_tag nhiều lần không?
Tim

và ... xin lỗi, hãy nhập sớm ... mỗi div / span lồng bên trong vẫn là một content_tag và bạn vẫn cần xác thực nó mặc dù phải không? Vì chúng tôi không thể thấy những gì bạn đang làm với bản dịch ưa thích của bạn ;-), tôi cho rằng bạn tìm kiếm TẤT CẢ các thẻ, bất kể regex có nằm trong 'cha mẹ' của html không, chẳng hạn như <ul>. bạn sẽ không đặt tất cả li như một chuỗi ass lớn để in chứ? mỗi người sẽ là nội dung của riêng mình: li, văn bản chính xác?
pjammer

0

@str = "<span class=\"classname\">hello</span>" Nếu theo quan điểm của tôi, tôi làm

<%raw @str %> Mã nguồn HTML là <span class=\"classname\">hello</span>nơi tôi thực sự muốn <span class="classname">hello</span>(không có dấu gạch chéo ngược đang thoát khỏi dấu ngoặc kép>). Cách tốt nhất để "unescape" những trích dẫn kép đó là gì?

Giải pháp: sử dụng dấu ngoặc kép bên trong dấu ngoặc đơn (hoặc dấu ngoặc đơn bên trong dấu ngoặc kép) để tránh thoát bằng dấu gạch chéo ngược.

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

0

Phiên bản html_safe hoạt động tốt trong Rails 4 ...

<%= "<center style=\"color: green; font-size: 1.1em\" > Administrators only </center>".html_safe if current_user.admin? %
>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.