Làm cách nào để mã hóa / giải mã các thực thể HTML trong Ruby?


200

Tôi đang cố gắng giải mã một số thực thể HTML, chẳng hạn như '&amp;lt;'trở thành '<'.

Tôi có một viên ngọc cũ ( html_helpers ) nhưng dường như nó đã bị bỏ rơi hai lần.

Có khuyến nghị nào không? Tôi sẽ cần phải sử dụng nó trong một mô hình.


6
Chỉ cần tìm thấy 'htmlentities' ( htmlentities.rubyforge.org )
Kostas

Tôi nên xác định rằng tôi nhận được html từ một loạt các trang web khác nhau và cần lưu nó dưới dạng văn bản thuần túy trong cơ sở dữ liệu
Kostas

1
Trong khi hầu hết các phiếu bầu đã sử dụng CGI, thì không. Điều đó giống như kéo theo tất cả Hỗ trợ tích cực để có một phương thức duy nhất. Thay vào đó, hãy sử dụng HTMLEntities, như được đề cập trong câu trả lời đã chọn.
Tin Man

Câu trả lời:


153

HTMLEntities có thể làm điều đó:

: jmglov@laurana; sudo gem install htmlentities
Successfully installed htmlentities-4.2.4
: jmglov@laurana;  irb
irb(main):001:0> require 'htmlentities'
=> []
irb(main):002:0> HTMLEntities.new.decode "&iexcl;I&#39;m highly&nbsp;annoyed with character references!"
=> "¡I'm highly annoyed with character references!"

Zdrasti Ivailo. Cám ơn bạn đã góp ý; nó đã giải quyết vấn đề của tôi về Làm cách nào tôi có thể hiển thị các tham chiếu thực thể ký tự XML trong Ruby? cũng!
Josh Glover

4
Yup, các HTMLEntitiesviên ngọc giao dịch với những trường hợp như &aring;&mdash;đó CGI.unescapeHTMLkhông.
thomax

295

Để mã hóa các ký tự, bạn có thể sử dụng CGI.escapeHTML:

string = CGI.escapeHTML('test "escaping" <characters>')

Để giải mã chúng, có CGI.unescapeHTML:

CGI.unescapeHTML("test &quot;unescaping&quot; &lt;characters&gt;")

Tất nhiên, trước đó bạn cần bao gồm thư viện CGI:

require 'cgi'

Và nếu bạn đang ở trong Rails, bạn không cần sử dụng CGI để mã hóa chuỗi. Có hphương pháp.

<%= h 'escaping <html>' %>

9
Tôi đã thử cách tiếp cận này trước nhưng nó không biến các thực thể như "& nbsp;" thành "". Tôi đoán tôi nên xác định rằng tôi lấy html từ một loạt các trang web khác nhau và cần lưu nó dưới dạng văn bản thuần túy trong cơ sở dữ liệu.
Kostas

2
Nếu bạn đang giải mã các thực thể HTML để lưu trữ dưới dạng văn bản thuần túy trong cơ sở dữ liệu, thì hãy hy vọng cơ sở dữ liệu của bạn sẽ phàn nàn nhiều về các ký tự xấu. Các thực thể được mã hóa được mã hóa để cho phép chúng chuyển dưới dạng văn bản thuần túy. Giải mã chúng có thể, và rất có thể sẽ, hoàn nguyên chúng thành các ký tự được đặt ở trên, nhị phân AKA. Gần như có khả năng, bạn có thể kết thúc với các ký tự đa nhân sẽ thực sự gây khó chịu cho một DB đang mong đợi văn bản thuần túy. Tốt hơn hết là bạn nên giải mã cho đến khi không có gì thay đổi, sau đó mã hóa một lần để mọi thứ được bình thường hóa, sau đó lưu trữ chúng.
Tin Man

1
Tôi đã gặp rất nhiều HTML với các thực thể được mã hóa nhiều lần, thực sự làm cho mọi thứ trở nên lộn xộn. Kiểm tra xơ mướp ; Nó chà được thiết kế cho điều này nếu tôi nhớ đúng.
Tin Man

3
Chúng tôi đã thiết lập cơ sở dữ liệu của mình để lưu Unicode, vì vậy tôi nghi ngờ nó sẽ phàn nàn. Và loofah không phải là thứ tôi đang tìm kiếm, tôi không muốn thoát khỏi các thẻ html - dù sao thì không phải lúc này.
Kostas

1
đó là năm 2015, unescapeHTML vẫn bỏ sót một số thực thể như A cấp tính
Nurettin

47

Tôi nghĩ đá quý Nokogiri cũng là một lựa chọn tốt. Nó rất ổn định và có một cộng đồng đóng góp rất lớn.

Mẫu:

a = Nokogiri::HTML.parse "foo&nbsp;b&auml;r"    
a.text 
=> "foo bär"

hoặc là

a = Nokogiri::HTML.parse "&iexcl;I&#39;m highly&nbsp;annoyed with character references!"
a.text
=> "¡I'm highly annoyed with character references!"

3
@theTinMan, vâng tôi nghĩ nó phụ thuộc vào nhu cầu. Như bạn có thể thấy qua các cuộc thảo luận trong chủ đề này, CGI.escapeHTMLcó thể không thể giải quyết một số trường hợp. Mặt khác, nếu bạn cần một bộ hỗ trợ đầy đủ, tôi chắc chắn Nokogirilà một lựa chọn tốt.
Hoàng Lê

6
Ngoài ra, nếu bạn đã sử dụng Nokogiri cho một số phân tích cú pháp HTML, việc cài đặt thêm một viên ngọc khác chỉ cho mục đích đó là không hợp lý. Chẳng hạn, tôi đang sử dụng đá quý Sanitize để dọn dẹp HTML. Hóa ra viên ngọc này đang sử dụng Nokogiri dưới mui xe và vì vậy thật đáng tiếc nếu không phiêu lưu về điều đó. Cảm ơn @HoangLe cho tiền boa!
Tomalla

1
Lưu ý: CGI::escapeHTMLkhông thoát khỏi các ký tự tiếng Đức như äöüß, và có thể hơn ... Với Nokogiri tôi chưa kiểm tra, nhưng đây sẽ là một điểm cộng.
Người đẹp

HTMLEntities sẽ là một lựa chọn gọn nhẹ và có khả năng. Tôi sử dụng Nokogiri rất nhiều, và, trừ khi tôi đã tải nó, tôi sẽ sử dụng HTMLEntities. CGI đã hết hạn.
Tin Man

36

Để giải mã các ký tự trong Rails, hãy sử dụng:

<%= raw '<html>' %>

Vì thế,

<%= raw '&lt;br&gt;' %>

sẽ xuất

<br>

5
Điều này chỉ hoạt động trong xem mặc dù. Tôi cũng cần một cái gì đó hoạt động trong ActiveRecord.
Kostas

3
Chỉ được thử nghiệm trong trình gỡ lỗi - raw '& lt br & gt' ==> '& lt br & gt'.
Sẽ Tomlins

13
#rawkhông giải mã bất cứ điều gì. Nó cho biết khung nhìn không mã hóa chuỗi. Nó thực hiện điều này bằng cách gói chuỗi trong a ActiveSupport::SafeBuffer, lần lượt có cờ ( html_safe?), được đặt thành true. Khung nhìn sử dụng cờ này để xác định rằng chuỗi có thể được chèn trực tiếp vào HTML mà không bị thoát. Tôi muốn nghĩ về html_safemột chỉ dẫn của lập trình viên rằng chuỗi trong câu hỏi đã được thoát đúng.
Moxley Stratton

9

Nếu bạn không muốn thêm một phụ thuộc mới chỉ để làm điều này (như HTMLEntities) và bạn đã sử dụng Hpricot, nó có thể thoát và không hiển thị cho bạn. Nó xử lý nhiều hơn CGI:

Hpricot.uxs "foo&nbsp;b&auml;r"
=> "foo bär"

5
Lưu ý cho những người nhìn vào điều này bây giờ - Hpricot không còn được duy trì.
SamStephens

2
Sử dụng Nokogiri , là tiêu chuẩn defacto cho phân tích cú pháp XML / HTML, thay vì Hpricot.
Tin Man

0

Bạn có thể sử dụng htmlasciiđá quý:

Htmlascii.convert string

-5
<% str="<h1> Test </h1>" %>

result: &lt; h1 &gt; Test &lt; /h1 &gt;

<%= CGI.unescapeHTML(str).html_safe %>

Tôi nghĩ rằng bằng cách thêm html_safe vào bất kỳ văn bản nào do người dùng nhập vào, bạn đang nói với quan điểm rằng nó an toàn khi có thể nó không an toàn. Điều này sẽ khiến người dùng của bạn gặp rủi ro khi họ tải chế độ xem đó.
dùng1515295

Tôi không biết tại sao lại tiêu cực như vậy. Tôi đã thử tất cả các giải pháp trong câu hỏi này. Chỉ điều này hoạt động tốt. Về HTML an toàn, người dùng MUỐN kết xuất HTML, sau đó HTML_SAFE là chính xác.
Diego Somar
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.