Ruby on Rails: วิธีการแสดงสตริงเป็น HTML?


154

ฉันมี

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

และในมุมมองของฉัน erb:

<%= @str %>

สิ่งที่จะแสดงบนหน้าคือ<b>Hi</b>เมื่อสิ่งที่ฉันต้องการจริงๆคือสวัสดี วิธี "ตีความ" สตริงของทับทิมเป็นมาร์กอัป HTML คืออะไร


แก้ไข : กรณีที่

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

ถ้าในมุมมองของฉันฉันทำ

<%raw @str %>

ซอร์สโค้ด HTML คือ<span class=\"classname\">hello</span> ที่สิ่งที่ฉันต้องการคือ<span class="classname">hello</span>(ไม่มีแบ็กสแลชที่หนีเครื่องหมายคำพูดคู่) อะไรคือวิธีที่ดีที่สุดในการ "unescape" เครื่องหมายคำพูดคู่นั้น


คุณอาจพิจารณาใช้ไวยากรณ์% Q [] สำหรับการหลบหนีสตริง เช่น %Q["quotation marks"] => "\"quotation marks\"" ที่มา: en.wikibooks.org/wiki/Ruby_Programming/Syntax/ … ไม่รู้ว่ามันช่วยได้หรือไม่
0112

คำตอบ:


328

UPDATE

ด้วยเหตุผลด้านความปลอดภัยก็จะแนะนำให้ใช้แทนsanitize ลิงค์html_safe


สิ่งที่เกิดขึ้นคือในฐานะมาตรการรักษาความปลอดภัย Rails กำลังหลบหนีสตริงของคุณให้คุณเพราะอาจมีโค้ดที่เป็นอันตรายฝังอยู่ แต่ถ้าคุณบอก Rails ว่าสตริงของคุณอยู่html_safeมันจะผ่านมันไป

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

หรือ

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

การใช้rawงานได้ผลดี แต่สิ่งที่ทำอยู่ก็คือการแปลงสตริงเป็นสตริงจากนั้นเรียกใช้ html_safe เมื่อฉันรู้ว่าฉันมีสตริงฉันชอบโทร html_safe โดยตรงเพราะข้ามขั้นตอนที่ไม่จำเป็นและทำให้ชัดเจนว่าเกิดอะไรขึ้น รายละเอียดเกี่ยวกับการป้องกันสตริงและการป้องกัน XSS อยู่ในAsciicastนี้


น่าอัศจรรย์ ฉันไม่สามารถหาวิธีที่จะทำได้แม้หลังจากค้นหาหนึ่งชั่วโมง ขอบคุณสำหรับคำตอบ.
Salil

1
rawผมเคยใช้เสมอ ดีใจมากที่รู้เรื่องนี้!
jmcharnes

ให้แฮงค์กับอนาคต =)
Carlos Morales

1
sanitize ถูกลบออกตามstackoverflow.com/questions/44575106/…
Youness

16

ใช้ดิบ :

<%=raw @str >

แต่ตามที่ @ jmort253 พูดอย่างถูกต้องให้พิจารณาว่า HTML นั้นอยู่ที่ใด


สวัสดีวิธีนี้ใช้ได้ผลยกเว้นมีข้อแม้หนึ่งข้อ: โปรดดูคำถามที่แก้ไขแล้ว
ทิม

14

หากคุณกำลังrailsใช้Erubisซึ่งเป็นวิธีที่ยอดเยี่ยมที่สุด

<%== @str >

สังเกตเครื่องหมายเท่ากับสองเท่า ดูคำถามที่เกี่ยวข้องกับ SO สำหรับข้อมูลเพิ่มเติม



7

คุณกำลังผสมตรรกะทางธุรกิจกับเนื้อหาของคุณ แต่ฉันขอแนะนำให้ส่งข้อมูลไปยังหน้าของคุณแล้วใช้บางอย่างเช่น JQuery เพื่อวางข้อมูลในที่ที่คุณต้องการ

นี่คือข้อดีของการเก็บ HTML ทั้งหมดไว้ในหน้า HTML ที่เป็นของมันเพื่อให้นักออกแบบเว็บไซต์ของคุณสามารถแก้ไข HTML ได้ในภายหลังโดยไม่ต้องเทรหัสฝั่งเซิร์ฟเวอร์

หรือถ้าคุณไม่ต้องการใช้จาวาสคริปต์คุณสามารถลองทำสิ่งนี้:

@str = "Hi"

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

อย่างน้อยทาง HTML ของคุณอยู่ในหน้า HTML ที่เป็นของมัน


ปัญหาคือแอปของฉันกำลังรับไฟล์ที่ทำเครื่องหมายไม่ดีและ "แปล" ผ่าน regexes เป็นมาร์กอัพ HTML ที่ดีเพื่อส่งไปยังมุมมอง ดังนั้นมาร์กอัป HTML ที่สร้างขึ้นนั้นเป็นแบบไดนามิกดังนั้นฉันจึงไม่สามารถทราบลำดับความสำคัญของแท็กที่ควรจะล้อมรอบ @str ฉันจะทำงาน "แปล" นี้ได้ที่ไหนถ้าไม่มีในรุ่น? ฉันคิดว่าเราไม่ควรมีรหัสลอจิกที่ครอบคลุมในมุมมอง
ทิม

1
มันเป็นเรื่องของความเห็น เมื่อพัฒนาแอปใหม่ฉันต้องการให้ทุกอย่างสะอาดที่สุด แต่บ่อยครั้งเราต้องทำงานภายใต้ข้อ จำกัด ของสิ่งที่คนอื่นทิ้งเราไว้ หากแหล่งข้อมูลของคุณส่งคืนมาร์กอัป HTML คุณอาจพิจารณาใช้ "raw" ดังอธิบายในโซลูชันของ Michael Stum
jmort253

1
หากคุณได้รับการสนับสนุนบางรหัสและรหัสมีพื้นที่ที่แสดงความคิดไม่ดีหรือการออกแบบมันเป็นส่วนหนึ่งของความรับผิดชอบของคุณในการทำความสะอาดมันเพื่อให้สามารถบำรุงรักษาได้มากขึ้น ออกจากที่คุณพบว่ามันเป็นเรื่องดีเมื่อมันเป็นรหัสที่ดีในการเริ่มต้น แต่ทิ้งไว้ดีกว่าที่คุณพบว่ามันเป็นเรื่องที่ดีเมื่อมันจำเป็นต้องทำงาน ส่วนหนึ่งของงานของฉันคือการจัดการแอพเก่า ฉันเป็นแฟนตัวยงของการไม่แก้ไขสิ่งที่ไม่แตกสลาย แต่พวกเขาไม่สามารถปรับปรุงได้อย่างง่ายดายเพราะสิ่งที่พวกเขาเขียน ฉันต้องเขียนการเรียกฟังก์ชันส่วนใหญ่ใหม่ แต่ตอนนี้ทำงานได้ง่ายขึ้นมาก
Tin Man

คุณไม่ควรใช้ JavaScript สำหรับการแก้ไข HTML ของคุณหากไม่มีเหตุผลอื่นที่จะใช้ JS ที่จะทำลายเว็บไซต์ของเบราว์เซอร์ที่ไม่ใช่ JS (ใช่มีอยู่บางส่วน)
Marnen Laibow-Koser

1
นอกหลักสูตรหากคุณอนุญาตให้เนื้อหาที่ไม่ถูกหลบหนีจะช่วยให้คุณมั่นใจว่ามาร์กอัปที่ไม่ใช่ความชั่วนั้นขึ้นอยู่กับคุณ
Macario

6

หรือคุณสามารถลองใช้วิธีCGI.unescapeHTML

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

0

เนื่องจากคุณกำลังแปลและหยิบรหัสที่คุณต้องการจากไฟล์รหัสเส็งเคร็งของบุคคลคุณสามารถใช้ content_tag พร้อมกับ regex ของคุณ

การขโมยจาก api docs คุณสามารถแก้ไขโค้ดที่แปลนี้ให้เป็นcontent_tagเช่น:

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

หากไม่ทราบรหัสของคุณการคิดแบบนี้จะทำให้แน่ใจว่ารหัสที่แปลของคุณนั้นสอดคล้องกับมาตรฐานเกินไป


ฉันสมมติว่า translate_text เป็นเนื้อหาจริงภายใน div ใช่ไหม เช่นในตัวอย่างมันจะเป็น "Hello world!" เกิดอะไรขึ้นถ้า translate_text มี HTML มากกว่านั้นเช่น divs หรือช่วงซ้อนกัน ฉันจะต้องโทรหา content_tag หลายครั้งไหม
ทิม

และ ... ขออภัยที่กดเข้ามาก่อน ... แต่ละ div / span ที่ซ้อนกันยังคงเป็น content_tag และคุณยังต้องตรวจสอบความถูกต้องใช่มั้ย เนื่องจากเราไม่สามารถเห็นสิ่งที่คุณกำลังทำกับการแปลแฟนซีของคุณ ;-) ฉันจะสมมติว่าคุณมองหาแท็กทั้งหมดโดยไม่คำนึงว่า regex อยู่ใน 'parent' ของ html ... เช่น <ul> คุณไม่คิดว่า li ทั้งหมดเป็นสายอักขระตัวพิมพ์ใหญ่ใช่ไหม แต่ละอันจะเป็นของตัวเอง content_tag: ใช่ข้อความถูกต้องหรือไม่
pjammer

0

@str = "<span class=\"classname\">hello</span>" ถ้าในมุมมองของฉันฉันทำ

<%raw @str %> ซอร์สโค้ด HTML คือ<span class=\"classname\">hello</span>ที่ที่ฉันต้องการคือ<span class="classname">hello</span>(ไม่มีแบ็กสแลชที่หนีเครื่องหมายคำพูดสองครั้ง>) อะไรคือวิธีที่ดีที่สุดในการ "unescape" เครื่องหมายคำพูดคู่นั้น

การแก้ไข: ใช้เครื่องหมายคำพูดคู่ภายในเครื่องหมายคำพูดเดี่ยว (หรือเครื่องหมายคำพูดเดี่ยวซ้อนทับในคู่) เพื่อหลีกเลี่ยงการหลบหลีกด้วยแบ็กสแลช

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

0

เวอร์ชั่น html_safe ทำงานได้ดีใน Rails 4 ...

<%= "<center style=\"color: green; font-size: 1.1em\" > Administrators only </center>".html_safe if current_user.admin? %
>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.