Internalhtml phản ứng tự nhiên

Bài viết này trình bày lý do đằng sau việc sử dụng thuộc tính dangerouslySetInnerHTML trong ứng dụng React, tương đương với thuộc tính innerHTML trong trình duyệt DOM

dangerouslySetInnerHTML là gì?

dangerouslySetInnerHTML là một thuộc tính mà bạn có thể sử dụng trên các phần tử HTML trong ứng dụng React để thiết lập nội dung của chúng theo chương trình. Thay vì sử dụng bộ chọn để lấy phần tử HTML, sau đó đặt innerHTML của nó, bạn có thể sử dụng thuộc tính này trực tiếp trên phần tử

Khi dangerouslySetInnerHTML được sử dụng, React cũng biết rằng nội dung của phần tử cụ thể đó là động và đối với nút con của nút đó, nó chỉ cần bỏ qua phần so sánh với DOM ảo để đạt được hiệu suất cao hơn

Như tên của thuộc tính gợi ý, nó có thể nguy hiểm khi sử dụng vì nó làm cho mã của bạn dễ bị tấn công bằng kịch bản chéo trang (XSS). Điều này trở thành một vấn đề đặc biệt nếu bạn đang tìm nạp dữ liệu từ nguồn của bên thứ ba hoặc hiển thị nội dung do người dùng gửi

Khi nào thì sử dụng dangerouslySetInnerHTML

Trường hợp sử dụng mà bạn cần đặt nội dung HTML của phần tử DOM là khi bạn điền phần tử

const App = () => {
  const data = 'lorem ipsum';

  return (
    
); } export default App;
4 với dữ liệu đến từ trình soạn thảo văn bản đa dạng thức. Hãy tưởng tượng bạn có một trang web nơi mọi người có thể gửi nhận xét và bạn cho phép họ sử dụng trình soạn thảo văn bản đa dạng thức. Trong trường hợp này, đầu ra của trình soạn thảo văn bản đa dạng thức đó có thể là HTML với các thẻ như
const App = () => {
  const data = 'lorem ipsum';

  return (
    
); } export default App;
5,
const App = () => {
  const data = 'lorem ipsum';

  return (
    
); } export default App;
6 và
const App = () => {
  const data = 'lorem ipsum';

  return (
    
); } export default App;
7

Consider the following code snippet, which would render the string without being aware of the

const App = () => {
  const data = 'lorem ipsum';

  return (
    
); } export default App;
6 tag in it — meaning that the output would be just the string itself without any bold text, like so: lorem ipsum.

const App = () => {
  const data = 'lorem ipsum';

  return (
    
{data}
); } export default App;

Nhưng khi sử dụng dangerouslySetInnerHTML, React sẽ nhận biết được các thẻ HTML và hiển thị chúng đúng cách. Lần này, đầu ra sẽ được hiển thị chính xác với văn bản in đậm (i. e. , lorem ipsum)

const App = () => {
  const data = 'lorem ipsum';

  return (
    
); } export default App;

Lưu ý rằng nó phải là một đối tượng có khóa

const App = () => {
  const data = `lorem ipsum`;

  return (
    
); } export default App; const App = () => { const data = `lorem ipsum `; return (
); } export default App;
0 được chuyển đến dangerouslySetInnerHTML. Ngoài ra, phần tử bạn sử dụng thuộc tính dangerouslySetInnerHTML không được có bất kỳ phần tử con nào, do đó việc sử dụng phần tử
const App = () => {
  const data = 'lorem ipsum';

  return (
    
); } export default App;
4 làm thẻ tự đóng

Yêu cầu chuyển một đối tượng chỉ là một biện pháp bảo vệ khác để ngăn các nhà phát triển sử dụng nó mà không xem qua tài liệu và nhận thức được mối nguy hiểm tiềm tàng

Vệ sinh khi sử dụng dangerouslySetInnerHTML

Các ví dụ trên không gây nguy hiểm khi kết xuất. Tuy nhiên, có thể có một số trường hợp phần tử HTML thực thi tập lệnh

Xem xét các ví dụ sau trong đó sự kiện JavaScript được đính kèm với phần tử HTML. Mặc dù đây là những ví dụ vô hại nhưng chúng là bằng chứng về các khái niệm cho thấy cách một phần tử HTML có thể bị khai thác để chạy các tập lệnh độc hại


Internalhtml phản ứng tự nhiên
Internalhtml phản ứng tự nhiên

Hơn 200 nghìn nhà phát triển sử dụng LogRocket để tạo ra trải nghiệm kỹ thuật số tốt hơn

Internalhtml phản ứng tự nhiên
Internalhtml phản ứng tự nhiên
Tìm hiểu thêm →


const App = () => {
  const data = `lorem ipsum`;

  return (
    
); } export default App; const App = () => { const data = `lorem ipsum `; return (
); } export default App;

May mắn thay, có các công cụ làm sạch cho HTML, giúp phát hiện các phần độc hại tiềm tàng trong mã HTML và sau đó xuất ra một phiên bản sạch và an toàn của nó. Trình khử trùng phổ biến nhất cho HTML là DOMPurify

Hãy sử dụng bản trình diễn trực tuyến của nó để làm sạch các mã HTML đã đề cập ở trên và xem cách nó phát hiện và lọc ra các phần mã có khả năng gây nguy hiểm khi thực thi

Original
lorem ipsum

Sanitized
lorem ipsum
Original
lorem ipsum 

Sanitized
lorem ipsum 

Đó là một phương pháp hay để sử dụng chất khử trùng ngay cả khi chúng ta tin tưởng vào nguồn dữ liệu. Với gói DOMPurify được sử dụng, một trong những ví dụ trên sẽ như sau

import DOMPurify from 'dompurify'

const App = () => {
  const data = `lorem ipsum`
  const sanitizedData = () => ({
    __html: DOMPurify.sanitize(data)
  })

  return (
    
); } export default App;

Hàm

const App = () => {
  const data = `lorem ipsum`;

  return (
    
); } export default App; const App = () => { const data = `lorem ipsum `; return (
); } export default App;
5 trả về một đối tượng có khóa
const App = () => {
  const data = `lorem ipsum`;

  return (
    
); } export default App; const App = () => { const data = `lorem ipsum `; return (
); } export default App;
0, có giá trị được trả về từ hàm
const App = () => {
  const data = `lorem ipsum`;

  return (
    
); } export default App; const App = () => { const data = `lorem ipsum `; return (
); } export default App;
7

Như mong đợi, khi chúng tôi di chuột qua văn bản in đậm, không có chức năng cảnh báo nào được thực hiện

Lưu ý rằng vì DOMPurify cần một cây DOM và môi trường Node không có, nên bạn phải sử dụng gói

const App = () => {
  const data = `lorem ipsum`;

  return (
    
); } export default App; const App = () => { const data = `lorem ipsum `; return (
); } export default App;
8 để tạo một đối tượng
const App = () => {
  const data = `lorem ipsum`;

  return (
    
); } export default App; const App = () => { const data = `lorem ipsum `; return (
); } export default App;
9 và khởi tạo
Original
lorem ipsum

Sanitized
lorem ipsum
0 với nó hoặc chỉ sử dụng gói
Original
lorem ipsum

Sanitized
lorem ipsum
1, gói gọn cả hai đối tượng
Original
lorem ipsum

Sanitized
lorem ipsum
0 và

Nếu bạn thích tùy chọn đầu tiên, bạn có thể tham khảo đoạn mã sau từ tài liệu của

Original
lorem ipsum

Sanitized
lorem ipsum
0

const createDOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');

const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);

const clean = DOMPurify.sanitize(dirty);

Phần kết luận

Tóm lại, dangerouslySetInnerHTML không gì khác ngoài sự thay thế của innerHTML trong React và nên được sử dụng cẩn thận. Mặc dù cái tên cho thấy sự nguy hiểm khi sử dụng, nhưng thực hiện biện pháp cần thiết bằng cách sử dụng trình khử trùng được phát triển tốt để đảm bảo mã sạch và không chạy các tập lệnh không mong muốn khi được hiển thị trong nút React