React:如何加载和呈现外部 html 文件?

IT技术 javascript html reactjs redux
2021-03-15 03:25:21

我使用 React 和 Redux 构建了一个小型博客应用程序。博客显示带有标题、作者、标签和帖子描述的帖子页面。当单击标题或“阅读更多”按钮时,我想从本地项目的数据文件夹中加载并呈现一个带有相应帖子的 HTML 文件,其中包含所有帖子。

Redux 正在管理博客的状态,加载带有 8 个不同帖子的初始 posts.json 文件,包括数据文件夹中相应 html 文件的 htmlPath。

4个回答

我的看法是你在这里有两个问题需要解决。第一个是如何innerHTML在 React 中设置元素的 。另一个是如何根据给定的变量(例如当前路由、文本字段的输入等)获取要呈现的特定 HTML。

1. 设置innerHTML元素的

你可以用dangerouslySetInnerHTMLprops做到这一点顾名思义,它将innerHTML所述元素的 设置为您指定的任何内容……是的,“危险”是准确的,因为它旨在让您在使用此功能之前三思而后行。

官方文档内容如下:

对innerHTML 的不当使用会使您面临跨站点脚本(XSS)攻击。众所周知,清理用于显示的用户输入容易出错,而未能正确清理是 Internet 上 Web 漏洞的主要原因之一。

查看此演示或下面的代码段。

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
    }
  );
}
我需要调整我的设置以使其正常工作,但我会尝试一下。感谢一百万@Chris
2021-04-20 03:25:21
加载外部 HTML 是否有安全且推荐的替代方法?
2021-04-24 03:25:21
@colecmc,不确定你的意思。你想达到什么目的?
2021-04-25 03:25:21
@colecmc,您是否尝试过上面的方法 1?
2021-04-30 03:25:21
所以我有一些 html 作为字符串,通过 fetch 调用检索。使用 vanillaJS 我会使用innerHTML或者insertAdjacentHTML()但是使用 React,我不确定最好的方法。我正在考虑将字符串转换为 JSON,然后通过循环 JSON 添加组件。
2021-05-10 03:25:21

虽然克里斯的回答很好,但需要更多的挖掘才能使其发挥作用。以下是您需要采取的步骤:

将 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} />)
}}
我已经完全按照你的描述做了,但我得到了一个页面的字符串,比如“samples/myHtmlCode.html”
2021-04-30 03:25:21
@r3wt,一年后我又来了,做我上面反对的事情......
2021-05-02 03:25:21
这不适用于从服务器获取 html,它仅使用 html 源作为数据 url 构建您的 webpack 项目(谁会想要这样做?)
2021-05-09 03:25:21
哦等等...我也有一些其他加载器的 .html 文件在测试中。现在它起作用了
2021-05-15 03:25:21

你可以试试react-templates这是'最好的'。你可以将你的模板作为一个外部文件,并且可以随时加载它,它会像所有可用的 React API 一样呈现魅力。

希望能帮助到你。

如果您真的确定,请使用服务器代码从文件系统中获取您喜欢的帖子内容,并将其显示在 React 组件中dangerouslySetInnerHTML

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

<div dangerouslySetInnerHTML={createMarkup()} />

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

我知道危险设置,我无法完成的事情是单击链接时,如何使用我在商店中的路径 ../../data/posts/html/[name].html 并加载文件的内容进入视野。
2021-05-05 03:25:21