简体   繁体   English

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

[英]React: how to load and render external html file?

I building a small blog app using React and Redux.我使用 React 和 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.单击标题或“阅读更多”按钮时,我想加载并呈现一个 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 个不同帖子的初始 posts.json 文件,包括数据文件夹中相应 html 文件的 htmlPath。

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.第一个是如何在 React 中设置元素的innerHTML The other is how to get a specific HTML to render depending on a given variable (eg the current route, the input of a textfield, etc).另一个是如何根据给定的变量(例如当前路由、文本字段的输入等)获取要呈现的特定 HTML。

1. Setting the innerHTML of an element 1. 设置元素的innerHTML

You can do this with the dangerouslySetInnerHTML prop.您可以使用dangerouslySetInnerHTML SetInnerHTML 道具来做到这一点。 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.顾名思义,它将所述元素的innerHTML设置为您指定的任何内容……是的,“危险”是准确的,因为它旨在让您在使用此功能之前三思而后行。

The Official Documentation reads as follows: 官方文档如下:

Improper use of the innerHTML can open you up to a cross-site scripting (XSS) attack.对innerHTML 的不当使用会使您面临跨站点脚本(XSS) 攻击。 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.众所周知,清理用于显示的用户输入容易出错,而未能正确清理是 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 2. 从外部获取 HTML

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 (eg php) read the file from a local folder, parse the text, and send it back through an AJAX request.动态获取选择特定文件的一种简单方法是让您的后端(例如 php)从本地文件夹读取文件,解析文本,然后通过 AJAX 请求将其发送回。

Example例子

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

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.config 文件中:

{
  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} />)
}}

You can try react-templates .你可以试试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 API 一样呈现魅力。

Hope it helps.希望能帮助到你。

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 :如果您真的确定,请使用服务器代码从文件系统中获取您喜欢的帖子内容,并使用dangerouslySetInnerHTML SetInnerHTML将其显示在React组件中:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM