redux React:如何加载和渲染外部HTML文件?

blmhpbnm  于 2023-08-05  发布在  React
关注(0)|答案(5)|浏览(273)

我用React和Redux开发了一个小博客。博客显示帖子页面,包括标题、作者、标签和帖子描述。当点击标题或“阅读更多”按钮时,我想从本地项目的数据文件夹中加载并呈现一个HTML文件,其中包含所有帖子。
Redux正在管理博客的状态,加载包含8个不同帖子的初始posts.json文件,包括data文件夹中相应html文件的htmlPath。

xmjla07d

xmjla07d1#

在我看来你有两个问题要解决。首先是如何在React中设置元素的innerHTML。另一个是如何根据给定的变量(例如当前路线,文本字段的输入等)来呈现特定的HTML。

1.设置元素的innerHTML

您可以使用dangerouslySetInnerHTML prop来完成此操作。顾名思义,它将所述元素的innerHTML设置为您指定的任何值...是的,“危险”是准确的,因为它的目的是让你在使用这个功能之前三思而后行。
Official Documentation的内容如下:
不正确地使用innerHTML会使您面临跨站脚本(XSS)攻击。众所周知,清理用户输入以供显示是容易出错的,并且未能正确清理是互联网上Web漏洞的主要原因之一。
看看这个Demo或下面的片段。

var Demo = React.createClass({

  getInitialState: function() {
    return {showExternalHTML: false};
  },
  
  render: function() {
    return (
      <div>
        <button onClick={this.toggleExternalHTML}>Toggle Html</button>
        {this.state.showExternalHTML ? <div>
          <div dangerouslySetInnerHTML={this.createMarkup()} ></div>
        </div> : null}
      </div>
    );
  },
  
  toggleExternalHTML: function() {
    this.setState({showExternalHTML: !this.state.showExternalHTML});
  },
  
  createMarkup: function() { 
    return {__html: '<div class="ext">Hello!</div>'};
  }

});

ReactDOM.render(
  <Demo />,
  document.getElementById('container')
);
.ext {
  margin-top: 20px;
  width: 100%;
  height: 100px;
  background: green;
  color: white;
  font-size: 40px;
  text-align: center;
  line-height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>

2.从外部获取HTML

请注意,上面的示例实际上并没有从外部文件中获取HTML,而是直接作为字符串输入。
一个简单的方法来做动态获取选择一个特定的文件将是让你的后端(例如php)从本地文件夹读取文件,解析文本,并通过 AJAX 请求发送回来。

示例

//Your React component
fetchExternalHTML: function(fileName) {
  Ajax.getJSON('/myAPI/getExternalHTML/' + fileName).then(
    response => {
      this.setState({
        extHTML: response
      });
    }, err => {
      //handle your error here
    }
  );
}

oxiaedzo

oxiaedzo2#

虽然克里斯的回答很好,但要让它起作用还需要更多的挖掘。以下是您需要采取的步骤:
将html加载器添加到项目中:

npm i -D html-loader

字符串
将以下规则添加到webpack.config文件:

{
  test: /\.(html)$/,
  use: {
    loader: 'html-loader',
    options: {
      attrs: [':data-src']
    }
  }
}


现在你可以导入你的html文件如下:

import React, { Component } from 'react';
import Page from './test.html';
var htmlDoc = {__html: Page};

export default class Doc extends Component {
  constructor(props){
    super(props);
  }

  render(){
     return (<div dangerouslySetInnerHTML={htmlDoc} />)
}}

wz1wpwve

wz1wpwve3#

如果你真的确定,可以从服务器代码的文件系统中获取文章内容到前端,并使用dangerouslySetInnerHTML在React组件中显示:

function createMarkup() { 
    return {__html: 'First &middot; Second'}; 
};

<div dangerouslySetInnerHTML={createMarkup()} />

字符串
更多文档:https://facebook.github.io/react/tips/dangerously-set-inner-html.html

2w2cym1i

2w2cym1i4#

你可以试试react-templates。这是“最好的”可用。你可以将你的模板作为一个外部文件,并且可以在你需要的时候加载它,它会像所有可用的React API一样呈现。
希望对你有帮助。

sbdsn5lh

sbdsn5lh5#

假设要包含的外部页面在应用编译时是未知的,并且您不需要应用和页面能够交互(例如,页面是一个独立的HTML,例如使用Markdown引擎渲染),iframe HTML元素可以很好地完成这项工作。(更多信息见https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe)。
语法如下:

<iframe src="link/to/your/html/page.html"></iframe>

字符串
然后.瞧,您的页面显示在iframe中。
它有一些优点:

  • 就是超级简单
  • 它创建了一个新的导航上下文,从而将外部页面与应用程序“隔离”,使其在显示用户提交的内容时相对安全,至少与直接包含相比。

还有一些缺点:

  • 由于隔离,您的应用程序的CSS将不会应用到页面,您必须手动将其包含在页面中。
  • 同样,你也不能从app中与页面DOM交互。也不是相反。
  • 与直接包含在应用程序中相比,具有多个导航上下文可能是昂贵的。这对于单个页面来说不是问题,但是如果你有百分之一的帖子,你可能必须确保不是所有的外部页面都同时显示(例如,make是这样的,一次只能应用view more
  • 页面中的链接不会受到应用程序最终链接解析的影响。这可能会迫使您在链接和路径方面保持两种不同的约定:一个是应用程序,一个是网页

相关问题