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

时间:2022-08-22 20:25:23

I building a small blog app using React and Redux. The blog show Posts page with title, author, tags and description of a post. When clicking on title or "read more" button, I want to load and render an HTML file with corresponding post from a local project's data folder with all the posts.

我用React和Redux开发了一个小型博客应用。这个博客显示了文章的标题、作者、标签和描述。当单击标题或“read more”按钮时,我希望加载并呈现一个HTML文件,其中包含来自本地项目数据文件夹的所有文章。

Redux is managing the state of the blog, loading initial posts.json file with 8 different posts, including htmlPath for the corresponding html file in the data folder.

Redux正在管理博客的状态,加载最初的文章。包含8个不同文章的json文件,包括数据文件夹中相应html文件的htmlPath。

4 个解决方案

#1


14  

The way I see it is that you have 2 problems to solve here. The first is how to set the innerHTML of an element in React. The other is how to get a specific HTML to render depending on a given variable (e.g the current route, the input of a textfield, etc).

我认为你有两个问题需要解决。第一个是如何在React中设置元素的innerHTML。另一个是如何根据给定的变量(e)获得要呈现的特定HTML。g当前路径、textfield的输入等)。

1. Setting the innerHTML of an element

You can do this with the dangerouslySetInnerHTML prop. As the name suggests it sets the innerHTML of the said element to whatever you specify... and yes, the "dangerously" is accurate as it's intended to make you think twice before using this feature.

你可以用危险的setinnerhtml道具做这个。顾名思义,它将上述元素的innerHTML设置为您指定的……是的,“危险”是准确的,因为它的目的是让你在使用这个功能之前三思。

The Official Documentation reads as follows:

官方文件内容如下:

Improper use of the innerHTML can open you up to a cross-site scripting (XSS) attack. Sanitizing user input for display is notoriously error-prone, and failure to properly sanitize is one of the leading causes of web vulnerabilities on the internet.

不当使用innerHTML可能导致跨站点脚本攻击。为显示而对用户输入进行消毒是出了名的容易出错,而未能正确地对其进行消毒是internet上web漏洞的主要原因之一。

Check out this Demo or the snippet below.

看看下面的演示或片段。

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. Fetching the HTML from an external source

Note that the above example does not actually get the HTML from an external file, but is entered directly as a string.

注意,上面的示例实际上并不从外部文件获取HTML,而是直接作为字符串输入。

One simple way to do dynamically fetch a choose a specific file would be to let your backend (e.g php) read the file from a local folder, parse the text, and send it back through an AJAX request.

动态获取选择文件的一种简单方法是让后端(e)。从本地文件夹中读取文件,解析文本,然后通过AJAX请求将其发回。

Example

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

#2


4  

While Chris's answer was good, some more digging was required to make it work. Here are the steps that you need to take:

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

Add html loader to your project:

向您的项目添加html加载程序:

npm i -D html-loader

Add the following rule to your webpack.config file:

将以下规则添加到webpack中。配置文件:

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

Now you can import your html file as follow:

现在您可以导入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} />)
}}

#3


0  

If you really sure, get the post contents to frontend how you like from file system with server code, and show it in React component with dangerouslySetInnerHTML:

如果你真的确定的话,让post内容在文件系统中以服务器代码的形式呈现你喜欢的内容,并在React组件中以dangerouslySetInnerHTML显示:

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

<div dangerouslySetInnerHTML={createMarkup()} />

More in docs: https://facebook.github.io/react/tips/dangerously-set-inner-html.html

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

#4


0  

You can try react-templates. This is 'the' best available. You can have your template as an external file and can load it whenever you want and it'll render like charm with all the React API available.

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

Hope it helps.

希望它可以帮助。

#1


14  

The way I see it is that you have 2 problems to solve here. The first is how to set the innerHTML of an element in React. The other is how to get a specific HTML to render depending on a given variable (e.g the current route, the input of a textfield, etc).

我认为你有两个问题需要解决。第一个是如何在React中设置元素的innerHTML。另一个是如何根据给定的变量(e)获得要呈现的特定HTML。g当前路径、textfield的输入等)。

1. Setting the innerHTML of an element

You can do this with the dangerouslySetInnerHTML prop. As the name suggests it sets the innerHTML of the said element to whatever you specify... and yes, the "dangerously" is accurate as it's intended to make you think twice before using this feature.

你可以用危险的setinnerhtml道具做这个。顾名思义,它将上述元素的innerHTML设置为您指定的……是的,“危险”是准确的,因为它的目的是让你在使用这个功能之前三思。

The Official Documentation reads as follows:

官方文件内容如下:

Improper use of the innerHTML can open you up to a cross-site scripting (XSS) attack. Sanitizing user input for display is notoriously error-prone, and failure to properly sanitize is one of the leading causes of web vulnerabilities on the internet.

不当使用innerHTML可能导致跨站点脚本攻击。为显示而对用户输入进行消毒是出了名的容易出错,而未能正确地对其进行消毒是internet上web漏洞的主要原因之一。

Check out this Demo or the snippet below.

看看下面的演示或片段。

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. Fetching the HTML from an external source

Note that the above example does not actually get the HTML from an external file, but is entered directly as a string.

注意,上面的示例实际上并不从外部文件获取HTML,而是直接作为字符串输入。

One simple way to do dynamically fetch a choose a specific file would be to let your backend (e.g php) read the file from a local folder, parse the text, and send it back through an AJAX request.

动态获取选择文件的一种简单方法是让后端(e)。从本地文件夹中读取文件,解析文本,然后通过AJAX请求将其发回。

Example

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

#2


4  

While Chris's answer was good, some more digging was required to make it work. Here are the steps that you need to take:

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

Add html loader to your project:

向您的项目添加html加载程序:

npm i -D html-loader

Add the following rule to your webpack.config file:

将以下规则添加到webpack中。配置文件:

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

Now you can import your html file as follow:

现在您可以导入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} />)
}}

#3


0  

If you really sure, get the post contents to frontend how you like from file system with server code, and show it in React component with dangerouslySetInnerHTML:

如果你真的确定的话,让post内容在文件系统中以服务器代码的形式呈现你喜欢的内容,并在React组件中以dangerouslySetInnerHTML显示:

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

<div dangerouslySetInnerHTML={createMarkup()} />

More in docs: https://facebook.github.io/react/tips/dangerously-set-inner-html.html

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

#4


0  

You can try react-templates. This is 'the' best available. You can have your template as an external file and can load it whenever you want and it'll render like charm with all the React API available.

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

Hope it helps.

希望它可以帮助。