如何访问 dangerous html 显示的数据
How to access data displayed by dangerous html
我有 table 正在使用危险的 HTML 在反应挂钩中显示
数据看起来像这样
export const json = [
{
template: `
<div ref={tableRef} className="table">
<table>
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Mark</td>
<td>Otto</td>
</tr>
</tbody>
</table>
</div>
`
}
];
此处显示的数据使用了 dangerousHTML
......
export default function App(props) {
const tableRef = useRef("");
let tables = data.json;
return (
<div className="App">
<input type="text" />
<div
ref={tableRef}
dangerouslySetInnerHTML={{ __html: tables[0].template }}
/>
</div>
);
}
问题:我需要做什么才能访问此 table 中的 table 数据(假设我想在输入更改时更改名称)?
首先,请谨慎使用此方法, as it's an easy way to open your users to XSS attacks。
In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack. So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML and pass an object with a __html key, to remind yourself that it’s dangerous.
也就是说,在这种情况下,您将不得不手动访问和管理危险集 HTML。
由于这是“副作用”的教科书示例,因此请在 useEffect
.
内进行管理
Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects. - https://reactjs.org/docs/hooks-effect.html
假设您为输入创建一个状态值 iVal
,您可以像这样更改 table 文本:
// ... New state:
const [iVal, setIVal] = React.useState("");
// ...
React.useEffect(() => {
console.log(tableRef);
if (iVal) {
tableRef.current
.getElementsByTagName("tbody")[0]
.getElementsByTagName("td")[1].innerHTML = iVal;
}
}, [iVal, tableRef]);
// ... Updated input:
<input
type="text"
value={iVal}
onChange={(e) => setIVal(e.target.value)}
/>
// ...
因此,由于 dependency array([iVal, tableRef]
),您的 useEffect
将在 iVal
(或 tableRef
)更改时更新。
从您的 codesandbox 派生的工作示例:
按照您设置的方式,从技术上讲,您可以使用 tableRef.current
间接访问 table 数据,这将为您提供对 HTMLDivElement 对象的引用,但您几乎将此代码重构为 not use dangerouslySetInnerHTML 肯定更好。
相反,您可能需要考虑将 table 数据存储为对象数组,例如:
[{firstName: "Mark", lastName: "Otto"}, {firstName: "Jack", lastName: "Antonoff"}]
您可以使用 useState
hook. To loop through and display the data, you'd use a simple map function as detailed in the React docs 存储和更新它,并为数组中的每个元素输出一个 table 行。
我有 table 正在使用危险的 HTML 在反应挂钩中显示
数据看起来像这样
export const json = [
{
template: `
<div ref={tableRef} className="table">
<table>
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Mark</td>
<td>Otto</td>
</tr>
</tbody>
</table>
</div>
`
}
];
此处显示的数据使用了 dangerousHTML
......
export default function App(props) {
const tableRef = useRef("");
let tables = data.json;
return (
<div className="App">
<input type="text" />
<div
ref={tableRef}
dangerouslySetInnerHTML={{ __html: tables[0].template }}
/>
</div>
);
}
问题:我需要做什么才能访问此 table 中的 table 数据(假设我想在输入更改时更改名称)?
首先,请谨慎使用此方法, as it's an easy way to open your users to XSS attacks。
In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack. So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML and pass an object with a __html key, to remind yourself that it’s dangerous.
也就是说,在这种情况下,您将不得不手动访问和管理危险集 HTML。
由于这是“副作用”的教科书示例,因此请在 useEffect
.
Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects. - https://reactjs.org/docs/hooks-effect.html
假设您为输入创建一个状态值 iVal
,您可以像这样更改 table 文本:
// ... New state:
const [iVal, setIVal] = React.useState("");
// ...
React.useEffect(() => {
console.log(tableRef);
if (iVal) {
tableRef.current
.getElementsByTagName("tbody")[0]
.getElementsByTagName("td")[1].innerHTML = iVal;
}
}, [iVal, tableRef]);
// ... Updated input:
<input
type="text"
value={iVal}
onChange={(e) => setIVal(e.target.value)}
/>
// ...
因此,由于 dependency array([iVal, tableRef]
),您的 useEffect
将在 iVal
(或 tableRef
)更改时更新。
从您的 codesandbox 派生的工作示例:
按照您设置的方式,从技术上讲,您可以使用 tableRef.current
间接访问 table 数据,这将为您提供对 HTMLDivElement 对象的引用,但您几乎将此代码重构为 not use dangerouslySetInnerHTML 肯定更好。
相反,您可能需要考虑将 table 数据存储为对象数组,例如:
[{firstName: "Mark", lastName: "Otto"}, {firstName: "Jack", lastName: "Antonoff"}]
您可以使用 useState
hook. To loop through and display the data, you'd use a simple map function as detailed in the React docs 存储和更新它,并为数组中的每个元素输出一个 table 行。