Và nó có thực sự rất nguy hiểm?
Ảnh của WocinTech Chat trên FlickrTrong bài viết này, chúng tôi sẽ thảo luận về dangerouslySetInnerHTML là gì, nó được sử dụng như thế nào, sự khác biệt giữa dangerouslySetInnerHTML và innerHTML, và một dự án thực sự mà nó chứng tỏ là hữu ích.
What?
dangerouslySetInnerHTML là một thuộc tính trong các thành phần DOM trong React.
Theo tài liệu chính thức, dangerouslySetInnerHTML đang phản ứng thay thế cho việc sử dụng innerHTML trong trình duyệt DOM.
Điều này có nghĩa là nếu trong phản ứng nếu bạn phải đặt HTML lập trình hoặc từ một nguồn bên ngoài, bạn sẽ phải sử dụng dangerouslySetInnerHTML thay vì truyền thống innerHTML trong JavaScript.
Nói một cách đơn giản, sử dụng dangerouslySetInnerHTML, bạn có thể đặt HTML trực tiếp từ React.
How?
Đầu tiên, hãy để Lừa xem cách function App(){ </div>)
return(
<div dangerouslySetInnerHTML={{ __html: `This text is set using dangerouslySetInnerHTML` }}>
}
Đây là mã JavaScript:
let root = document.querySelector('#root')root.innerHTML = `<h2>This text is set using innerHTML</h2>`
Sử dụng innerHTML rất đơn giản. Bạn chỉ cần sử dụng nó bằng cách sử dụng ký hiệu DOT với phần tử DOM và chuyển chuỗi HTML bằng cách sử dụng các trích dẫn hoặc nghĩa đen.
Bây giờ, hãy để xem cách đạt được như thế nào khi sử dụng dangerouslySetInnerHTML. (//codepen.io/lelouchb/pen/poprqew)
dangerouslySetInnerHTMLCode:
function App(){return(
<div dangerouslySetInnerHTML={{ __html: `This text is set using dangerouslySetInnerHTML` }}>
</div>)
}
Trong khi sử dụng dangerouslySetInnerHTML, bạn sẽ phải truyền một đối tượng có khóa function App(){ </div>) </div>)
const markup={ __html: 'This text is set using dangerouslySetInnerHTML'}
return(
<div dangerouslySetInnerHTML={markup}>
}
ReactDOM.render(<App />, document.querySelector("#root"));
const markup={ __html: 'This text is set using dangerouslySetInnerHTML'}
return(
<div dangerouslySetInnerHTML={markup}>
}
ReactDOM.render(<App />, document.querySelector("#root"));
Như một biến:
function App(){const markup={ __html: 'This text is set using dangerouslySetInnerHTML'}
return(
<div dangerouslySetInnerHTML={markup}>
</div>)
}
ReactDOM.render(<App />, document.querySelector("#root"));
Như một chức năng:
function App(){const markup=()=>{return{ __html: 'This text is set using dangerouslySetInnerHTML'}}
return(
<div dangerouslySetInnerHTML={markup()}>
</div>)
}
ReactDOM.render(<App />, document.querySelector("#root"));
Sự khác biệt
Hiệu quả ngay lập tức của việc sử dụng innerHTML so với dangerouslySetInnerHTML là giống hệt nhau: nút DOM sẽ cập nhật với HTML được tiêm. Tuy nhiên, đằng sau hậu trường, khi bạn sử dụng nó, nó cho phản ứng biết rằng HTML bên trong thành phần đó không phải là thứ mà nó quan tâm.
Bởi vì React sử dụng một DOM ảo, khi nó so sánh sự khác biệt với DOM thực tế, nó có thể vượt qua việc bỏ qua kiểm tra trẻ em của nút đó vì nó biết HTML đến từ một nguồn khác. Vì vậy, có hiệu suất tăng.
Quan trọng hơn, nếu bạn chỉ cần sử dụng innerHTML, React không có cách nào để biết nút dom đã được sửa đổi. Lần tiếp theo hàm function App(){ </div>)
const markup={ __html: 'This text is set using dangerouslySetInnerHTML'}
return(
<div dangerouslySetInnerHTML={markup}>
}
ReactDOM.render(<App />, document.querySelector("#root"));
Tại sao nguy hiểm?
Việc sử dụng không đúng cách innerHTML có thể mở ra cho bạn một cuộc tấn công kịch bản chéo (XSS). Tên prop dangerouslySetInnerHTML được chọn một cách có chủ ý là đáng sợ và giá trị prop (một đối tượng thay vì một chuỗi) có thể được sử dụng để chỉ ra dữ liệu vệ sinh. Bạn cần đảm bảo HTML của bạn được cấu trúc đúng và vệ sinh trước khi chèn nó vào trang của bạn. Bạn có thể sử dụng các thư viện như Dompurify để làm như vậy.
When?
Tên prop được cố ý chọn để sợ hãi vì vậy khi nó nên được sử dụng? Hãy để thảo luận về một dự án React ngoài đời thực, một nhà phát triển sẽ phải sử dụng dangerouslySetInnerHTML.where a developer will have to use dangerouslySetInnerHTML.
HackerNewsapi
Các dự án được thực hiện bằng API HackerNews rất phổ biến, đơn giản để thực hiện và thú vị, nhưng hầu hết các yêu cầu API được thực hiện trong đó là dành cho ID của các mục của function App(){ </div>)
const markup={ __html: 'This text is set using dangerouslySetInnerHTML'}
return(
<div dangerouslySetInnerHTML={markup}>
}
ReactDOM.render(<App />, document.querySelector("#root"));
const markup=()=>{return{ __html: 'This text is set using dangerouslySetInnerHTML'}}
return(
<div dangerouslySetInnerHTML={markup()}>
</div>)
}
ReactDOM.render(<App />, document.querySelector("#root"));
const markup={ __html: 'This text is set using dangerouslySetInnerHTML'}
return(
<div dangerouslySetInnerHTML={markup}>
</div>)
}
ReactDOM.render(<App />, document.querySelector("#root"));
//hacker-news.firebaseio.com/v0/item/23331287.json?print=pretty
{"by" : "lostmsu",
"descendants" : 251,
"id" : 23331287,
"kids" : [ 23332582, 23333565, 23332777, 23334075, 23331976, 23332122, 23332664, 23332047, 23333745, 23332119, 23332909, 23332118, 23332674, 23333572, 23334374, 23331882, 23334410, 23331780, 23332176, 23331823, 23332297, 23333192, 23333690, 23334269, 23332755, 23333735, 23333025, 23331297, 23333672, 23332123, 23332298, 23332913, 23333112, 23334176, 23333814, 23333849, 23334245, 23333261, 23332823, 23332079, 23331890, 23332360, 23332197, 23332840 ],
"score" : 844,
"time" : 1590620950,
"title" : "The Day AppGet Died",
"type" : "story",
"url" : "//keivan.io/the-day-appget-died/"
}
Nhưng yêu cầu được thực hiện cho các mục trong function App(){ </div>)
const markup=()=>{return{ __html: 'This text is set using dangerouslySetInnerHTML'}}
return(
<div dangerouslySetInnerHTML={markup()}>
}
ReactDOM.render(<App />, document.querySelector("#root"));
//hacker-news.firebaseio.com/v0/item/23325385.json?print=pretty
{"by" : "behnamoh",
"descendants" : 3,
"id" : 23325385,
"kids" : [ 23326663, 23326382, 23325618 ],
"score" : 1,
"text" : "As a heavy user, I basically <i>live</i> in my browser. However, extensions do slow down the browser, which makes me think there's gotta be a better way. I believe it's high time we had an operating system which is fully optimized as a browser. Extensions then, would be apps on the OS, and probably won't slow it down. Have you seen any OS that is browser-first?",
"time" : 1590595712,
"title" : "Ask HN: Can operating systems be browsers?",
"type" : "story"
}
Như bạn có thể thấy, function App(){ </div>)
const markup=()=>{return{ __html: 'This text is set using dangerouslySetInnerHTML'}}
return(
<div dangerouslySetInnerHTML={markup()}>
}
ReactDOM.render(<App />, document.querySelector("#root"));
Dưới đây là trường hợp sử dụng thực tế của dangerouslySetInnerHTML và các phản hồi như đã thảo luận ở trên được hiển thị trong HTML bằng cách sử dụng dangerouslySetInnerHTML.
Cảm ơn vì đã đọc!