Javascript React教程示例在example.js:42中抛出错误

Javascript React教程示例在example.js:42中抛出错误,javascript,php,jquery,json,reactjs,Javascript,Php,Jquery,Json,Reactjs,我正在尝试运行React教程中提供的示例代码: 我已经下载了示例代码,并将其放在我的MAMP安装的htdocs文件夹中 我在浏览器中输入“”,标题为“评论”,出现两个表单字段和一个post按钮,但没有评论。我假设json文件中的两条注释应该出现 我的目录结构与git项目相同,在主web文件夹中有php和json文件,在公共文件夹中有html、css和javascript文件 example.js在第34行抛出此错误 /未找到api/注释错误 我认为这可能与我本地机器上的ajax调用有关,但我已

我正在尝试运行React教程中提供的示例代码:

我已经下载了示例代码,并将其放在我的MAMP安装的htdocs文件夹中

我在浏览器中输入“”,标题为“评论”,出现两个表单字段和一个post按钮,但没有评论。我假设json文件中的两条注释应该出现

我的目录结构与git项目相同,在主web文件夹中有php和json文件,在公共文件夹中有html、css和javascript文件

example.js在第34行抛出此错误

/未找到api/注释错误

我认为这可能与我本地机器上的ajax调用有关,但我已经将示例上传到远程服务器,并且得到了相同的错误

jquery.min.js还在第4行抛出一个错误:

404(未找到)

但我假设这是因为example.js引起的上游错误

/**
 * This file provided by Facebook is for non-commercial testing and evaluation
 * purposes only. Facebook reserves all rights not expressly granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

var Comment = React.createClass({
  rawMarkup: function() {
    var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
    return { __html: rawMarkup };
  },

  render: function() {
    return (
      <div className="comment">
        <h2 className="commentAuthor">
          {this.props.author}
        </h2>
        <span dangerouslySetInnerHTML={this.rawMarkup()} />
      </div>
    );
  }
});

var CommentBox = React.createClass({
  loadCommentsFromServer: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  handleCommentSubmit: function(comment) {
    var comments = this.state.data;
    // Optimistically set an id on the new comment. It will be replaced by an
    // id generated by the server. In a production application you would likely
    // not use Date.now() for this and would have a more robust system in place.
    comment.id = Date.now();
    var newComments = comments.concat([comment]);
    this.setState({data: newComments});
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: comment,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        this.setState({data: comments});
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  getInitialState: function() {
    return {data: []};
  },
  componentDidMount: function() {
    this.loadCommentsFromServer();
    setInterval(this.loadCommentsFromServer, this.props.pollInterval);
  },
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList data={this.state.data} />
        <CommentForm onCommentSubmit={this.handleCommentSubmit} />
      </div>
    );
  }
});

var CommentList = React.createClass({
  render: function() {
    var commentNodes = this.props.data.map(function(comment) {
      return (
        <Comment author={comment.author} key={comment.id}>
          {comment.text}
        </Comment>
      );
    });
    return (
      <div className="commentList">
        {commentNodes}
      </div>
    );
  }
});

var CommentForm = React.createClass({
  getInitialState: function() {
    return {author: '', text: ''};
  },
  handleAuthorChange: function(e) {
    this.setState({author: e.target.value});
  },
  handleTextChange: function(e) {
    this.setState({text: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    var author = this.state.author.trim();
    var text = this.state.text.trim();
    if (!text || !author) {
      return;
    }
    this.props.onCommentSubmit({author: author, text: text});
    this.setState({author: '', text: ''});
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input
          type="text"
          placeholder="Your name"
          value={this.state.author}
          onChange={this.handleAuthorChange}
        />
        <input
          type="text"
          placeholder="Say something..."
          value={this.state.text}
          onChange={this.handleTextChange}
        />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

ReactDOM.render(
  <CommentBox url="/api/comments" pollInterval={2000} />,
  document.getElementById('content')
);
我错过什么了吗

这是我的index.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>React Tutorial</title>
        <!-- Not present in the tutorial. Just for basic styling. -->
        <link rel="stylesheet" href="css/base.css" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.6.15/browser.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.min.js"></script>
      </head>
      <body>
        <div id="content"></div>
        <script type="text/babel" src="scripts/example.js"></script>
        <script type="text/babel">
          // To get started with this tutorial running your own code, simply remove
          // the script tag loading scripts/example.js and start writing code here.
        </script>
      </body>
    </html>

反应教程
//要开始本教程运行您自己的代码,只需删除
//脚本标记加载scripts/example.js并在此处开始编写代码。
下面是我的示例.js

/**
 * This file provided by Facebook is for non-commercial testing and evaluation
 * purposes only. Facebook reserves all rights not expressly granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

var Comment = React.createClass({
  rawMarkup: function() {
    var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
    return { __html: rawMarkup };
  },

  render: function() {
    return (
      <div className="comment">
        <h2 className="commentAuthor">
          {this.props.author}
        </h2>
        <span dangerouslySetInnerHTML={this.rawMarkup()} />
      </div>
    );
  }
});

var CommentBox = React.createClass({
  loadCommentsFromServer: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  handleCommentSubmit: function(comment) {
    var comments = this.state.data;
    // Optimistically set an id on the new comment. It will be replaced by an
    // id generated by the server. In a production application you would likely
    // not use Date.now() for this and would have a more robust system in place.
    comment.id = Date.now();
    var newComments = comments.concat([comment]);
    this.setState({data: newComments});
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: comment,
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        this.setState({data: comments});
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  getInitialState: function() {
    return {data: []};
  },
  componentDidMount: function() {
    this.loadCommentsFromServer();
    setInterval(this.loadCommentsFromServer, this.props.pollInterval);
  },
  render: function() {
    return (
      <div className="commentBox">
        <h1>Comments</h1>
        <CommentList data={this.state.data} />
        <CommentForm onCommentSubmit={this.handleCommentSubmit} />
      </div>
    );
  }
});

var CommentList = React.createClass({
  render: function() {
    var commentNodes = this.props.data.map(function(comment) {
      return (
        <Comment author={comment.author} key={comment.id}>
          {comment.text}
        </Comment>
      );
    });
    return (
      <div className="commentList">
        {commentNodes}
      </div>
    );
  }
});

var CommentForm = React.createClass({
  getInitialState: function() {
    return {author: '', text: ''};
  },
  handleAuthorChange: function(e) {
    this.setState({author: e.target.value});
  },
  handleTextChange: function(e) {
    this.setState({text: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    var author = this.state.author.trim();
    var text = this.state.text.trim();
    if (!text || !author) {
      return;
    }
    this.props.onCommentSubmit({author: author, text: text});
    this.setState({author: '', text: ''});
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input
          type="text"
          placeholder="Your name"
          value={this.state.author}
          onChange={this.handleAuthorChange}
        />
        <input
          type="text"
          placeholder="Say something..."
          value={this.state.text}
          onChange={this.handleTextChange}
        />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

ReactDOM.render(
  <CommentBox url="/api/comments" pollInterval={2000} />,
  document.getElementById('content')
);
/**
*Facebook提供的此文件用于非商业测试和评估
*只是目的而已。Facebook保留所有未明确授予的权利。
*
*本软件按“原样”提供,无任何形式的明示或明示担保
*默示,包括但不限于适销性保证,
*适用于特定目的和非侵权。在任何情况下均不得
*FACEBOOK应承担任何索赔、损害赔偿或其他责任,无论是在
*合同诉讼、侵权诉讼或其他诉讼,由、由或与之相关
*与软件或软件的使用或其他交易有关。
*/
var Comment=React.createClass({
rawMarkup:function(){
var rawMarkup=marked(this.props.children.toString(),{sanitize:true});
返回{uuuhtml:rawMarkup};
},
render:function(){
返回(
{this.props.author}
);
}
});
var CommentBox=React.createClass({
loadCommentsFromServer:函数(){
$.ajax({
url:this.props.url,
数据类型:“json”,
cache:false,
成功:功能(数据){
this.setState({data:data});
}.绑定(此),
错误:函数(xhr、状态、错误){
console.error(this.props.url,status,err.toString());
}.绑定(此)
});
},
handleCommentSubmit:函数(注释){
var注释=this.state.data;
//乐观地在新评论上设置id。它将被替换为
//由服务器生成的id。在生产应用程序中
//不使用Date.now()进行此操作,系统将更加健壮。
comment.id=Date.now();
var newComments=comments.concat([comment]);
this.setState({data:newcommons});
$.ajax({
url:this.props.url,
数据类型:“json”,
键入:“POST”,
数据:评论,
成功:功能(数据){
this.setState({data:data});
}.绑定(此),
错误:函数(xhr、状态、错误){
this.setState({data:comments});
console.error(this.props.url,status,err.toString());
}.绑定(此)
});
},
getInitialState:函数(){
返回{data:[]};
},
componentDidMount:function(){
this.loadCommentsFromServer();
setInterval(this.loadCommentsFromServer,this.props.pollInterval);
},
render:function(){
返回(
评论
);
}
});
var CommentList=React.createClass({
render:function(){
var commentNodes=this.props.data.map(函数(注释){
返回(
{comment.text}
);
});
返回(
{commentNodes}
);
}
});
var CommentForm=React.createClass({
getInitialState:函数(){
返回{作者:'',文本:'};
},
handleAuthorChange:函数(e){
this.setState({author:e.target.value});
},
handleTextChange:函数(e){
this.setState({text:e.target.value});
},
handleSubmit:函数(e){
e、 预防默认值();
var author=this.state.author.trim();
var text=this.state.text.trim();
如果(!text | |!author){
回来
}
this.props.onCommentSubmit({作者:作者,文本:文本});
this.setState({author:'',text:''});
},
render:function(){
返回(
);
}
});
ReactDOM.render(
,
document.getElementById('content')
);

提供的示例服务器(请参阅本教程的README.md)具有路由“/api/comments”url的配置,而您的独立服务器没有配置该url。可以将其添加到服务器中,或者更简单地说,只需使用一个示例服务器脚本。

您需要阅读教程代码中包含的自述文件。您需要运行他们的服务器实现来提供/api/comments端点。

那么您的代码中遗漏了一些内容。我刚刚下载了示例并复制到目录中。我还没有触及代码。您是否正在运行服务器选项之一来承载comments api?我在远程WAMP堆栈和本地MAMP堆栈上进行了尝试。两个地方都有同样的错误。我需要进行任何特殊的服务器设置吗?我在这里没有看到任何指示嘿,我知道这是关闭的,但同样的事情发生在我身上。我通过进入运行“server.py”的服务器的Python模块并将文件读取模式从“r”更改为“r+”,解决了这个问题。以防万一其他人也有同样的问题。非常感谢。我必须做的另一件事是将comments.json文件移动到publi中