代码之家  ›  专栏  ›  技术社区  ›  catandmouse

如何在危险的HTML中使用<Link/>组件

  •  5
  • catandmouse  · 技术社区  · 5 年前

    目前,我在我的一个组件中有:

    {someObject.map(obj => (
        <div
            dangerouslySetInnerHTML={{
                __html: obj.text
            }}
        />
    ))}
    

    someObject 在另一个文件中。结构如下:

    export default someObject = [
          {
             obj: "<p>Some text 1.</p>"
          },
          {
             obj: "<p>Some text 2.</p>"
          }
        ]
    

    为了演示,我只是简化了内容。但是,我遇到了一个问题,因为我需要使用 <Link /> 其中一个项目中的组件。例如:

    export default someObject = [
        {
            obj: "<p>Some text 1.</p>"
        },
        {
            obj: "<p>Some text 2.</p>"
        },
        {
            obj: "<p>Some text 2 and <Link to="/someroute">link</Link>.</p>"
        }
    ]
    

    但是,它不起作用,因为整个 <p></p> 标签被包裹在里面 dangerouslySetInnerHTML

    我可以用普通的 <a></a> 标记链接,但这似乎不是一个好的解决方案,因为整个应用程序将重新加载,而不仅仅是转到另一个路由。

    还有什么其他办法可以让这一切顺利进行?

    3 回复  |  直到 5 年前
        1
  •  2
  •   Hai Pham    5 年前

    为什么不将对象导出为jsx对象呢?我想用 dangerouslySetInnerHTML 是一种不好的做法,它可能会导致XSS攻击。

    const someObject = [
      {
        obj: <p>Some text 1.</p>
      },
      {
        obj: <p>Some text 2.<a href="https://google.com">google</a></p>
      }
    ]
    class App extends React.Component {
      render(){ 
        return (
        <div className="App">
          <h1>Hello world</h1>
          <h2>Jsx object goes here {someObject[1].obj}</h2>
        </div>
      )};
    }
    
    const rootElement = document.getElementById("container");
    ReactDOM.render(<App />, rootElement);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.min.js"></script>
    <div id="container">
        <!-- This element's contents will be replaced with your component. -->
    </div>
        2
  •  0
  •   Community SqlRyan    4 年前
    • 有两种方法可以解决此问题:

    第一种方式:

    尝试使用这个库( https://github.com/tasti/react-linkify/

    下面是组件的简单形式:

    import React, {PropTypes} from 'react';
    import Linkify from 'react-linkify';
    
    export default class TextWithLink extends React.Component {
        constructor(props) {
          super(props);
        }
    
        render() {
          let text = this.props.text;
          if(this.props.showLink) {
            text = <Linkify properties={{target: '_blank', rel: "nofollow   noopener"}}>{text}</Linkify>
          }
          return (<div>{text}</div>);
        }
    }

    第二种方式:

    在这种情况下,如果要创建超链接( <a> ),您应该有一个函数来构建元素并返回结果。

    例子:

    list = {
      text: 'hello world',
      link: 'www.facebook.com'
    }

    渲染功能可能类似于:

    buildLink() {
       return(
          <p>
            {list.text}. <a href={list.link}>{list.link}</a>
          </p>
        );
    }
    
    render() {
       return (this.buildLink());
    }
        3
  •  -1
  •   prabin badyakar    5 年前
    export default someObject = [
        {
            obj: "<p>Some text 1.</p>"
        },
        {
            obj: "<p>Some text 2.</p>"
        },
        {
            obj: linkto('/someroute')
        }
    ]
    

    linkto将解决您的问题。