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

Int*_*dos 23 html javascript reactjs redux

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

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

Chr*_*ris 20

我看待它的方式是你要解决2个问题.第一个是如何innerHTML在React中设置元素.另一种是如何根据给定变量(例如,当前路线,文本字段的输入等)获取要呈现的特定HTML.

1.设置innerHTML元素

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

官方文档内容如下:

不正确地使用innerHTML可以让您进行跨站点脚本(XSS)攻击.消除用户输入以进行显示非常容易出错,无法正确消毒是导致互联网上网络漏洞的主要原因之一.

看看这个演示或下面的代码片段.

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')
);
Run Code Online (Sandbox Code Playgroud)
.ext {
  margin-top: 20px;
  width: 100%;
  height: 100px;
  background: green;
  color: white;
  font-size: 40px;
  text-align: center;
  line-height: 100px;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


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
    }
  );
}
Run Code Online (Sandbox Code Playgroud)


Ada*_*ani 9

虽然克里斯的答案很好,但还需要进行一些挖掘才能使其发挥作用.以下是您需要采取的步骤:

将html加载器添加到您的项目:

npm i -D html-loader
Run Code Online (Sandbox Code Playgroud)

将以下规则添加到webpack.config文件中:

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

现在您可以导入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} />)
}}
Run Code Online (Sandbox Code Playgroud)

  • @r3wt 一年后我再次在这里做我上面反对的事情...... (8认同)

Ale*_*nko 0

如果您确实确定,请使用服务器代码从文件系统获取帖子内容到前端,并使用以下命令在 React 组件中显示它dangerouslySetInnerHTML

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

<div dangerouslySetInnerHTML={createMarkup()} />
Run Code Online (Sandbox Code Playgroud)

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