【问题标题】:Why does my webpage refresh after a NodeJS POST request?为什么我的网页在 NodeJS POST 请求后刷新?
【发布时间】:2018-12-31 11:41:42
【问题描述】:

我正在使用带有 NodeJS 的 express 框架。当客户端发出 POST 请求时,它会将一些工作推送到 python 脚本,然后返回一个 JSON 对象到客户端网页。

我的问题是每当我的 POST 请求完成时客户端都会刷新。我已经使用 Axios 和 Fetch http 客户端进行了测试。 在发出这样的 POST 请求时如何防止我的网页刷新?

服务器代码如下所示:

app.post("/data/", function(req, res) { 

    const spawn = require("child_process").spawn;
    const pythonProcess = spawn('python', ["my_script.py"]);

    pythonProcess.stdout.on('data', (data) => {
          let result = data.toString();
          res.send(JSON.stringify(result));
     });
});

然后我从我的 React 客户端发出请求(使用 Axios,但 Fetch 的行为方式相同):

axios({
  method: 'post',
  url: `http://localhost:3001/videos/?url=${url}`,
  responseType: 'json',
});

并且客户端网页刷新...

我知道 React 不应该受到责备,因为没有任何东西会更新应用程序状态。即使我对来自服务器的响应什么都不做,当 POST 完成时,网页仍然会刷新。

另外,我的网页上没有表单元素或类似的东西,我的buttonbutton 类型而不是submit 类型。

我有一种预感,这与调用 python 进程本身的方式有关,因为如果我只返回一个普通的 JSON 对象而不调用 python 子进程,我的客户端网页会获取数据并且不会刷新。

【问题讨论】:

  • 表单上按钮的默认操作是提交,因此您可能需要在按钮处理程序中阻止它。
  • 我试过了。我真的认为这是一个服务器端的问题。但以防万一,我尝试添加preventDefault 等。没有运气
  • 极不可能是服务器端问题 - 服务器无法控制这样的浏览器,尤其是在 AJAX 请求时 - 浏览器开发者工具控制台会发生什么?

标签: javascript node.js express fetch axios


【解决方案1】:

我想通了。我的 python 进程的一部分是将文件写入 React 的 public 文件夹,这显然会导致 React 热重载。

【讨论】:

  • 这是我的问题,而不是其他答案中提到的 type='button' ,拯救了我的一天
【解决方案2】:

如果您基于从<form> 收集的数据发布 nodeJS 帖子 - 在用户单击 type=submit 的按钮之后,那么问题是表单提交按钮的原生 HTML 行为是页面刷新。

解决此问题的方法是 - 在您的提交表单中,可能是该 handleSubmit 函数上的 onSubmit={handleSubmit},让它接受一个事件,随心所欲地调用它。然后在任何其他代码之前执行 event.preventDefault() 。像这样:

handleSubmit(e){
   e.preventDefault();
  // the rest of your code, post call ,etc
}

【讨论】:

    【解决方案3】:

    我在 ReactJS 客户端 axios.post 中遇到了这个问题。我最初忽略了这个承诺,但在添加了一个 .then() 之后,问题就消失了。但是我不知道添加 .then() 是如何解决问题的

    【讨论】:

    • 这并不能真正回答问题。如果您有其他问题,可以点击 提问。要在此问题有新答案时收到通知,您可以follow this question。一旦你有足够的reputation,你也可以add a bounty 来引起对这个问题的更多关注。 - From Review
    【解决方案4】:

    SeanMC 的回答对我不起作用,但让我找到了正确的方向。

    确实,如果在表单中使用<input type="submit">,页面会在操作后自动刷新。但是,如果您改用<input type="button">,您仍然可以使用 onClick 操作而无需自动刷新页面。

    【讨论】:

      【解决方案5】:

      我认为,您需要更改响应标头,即响应类型为 json 类型。

      var headers = {};
      headers["Content-Type"] = 'application/json';
      res.writeHead(200, headers);
      
      app.options('/*', function (req, res) {
      var headers = {};
      
      // set header to handle the CORS
      headers['Access-Control-Allow-Origin'] = '*';
      //headers['Access-Control-Allow-Origin'] = 'http://localhost:?';
      headers['Access-Control-Allow-Headers'] = 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With';
      headers['Access-Contrl-Allow-Methods'] = 'PUT, POST, GET, DELETE, OPTIONS';
      headers["Access-Control-Max-Age"] = '86400';
      headers["Content-Type"] = 'application/json';
      res.writeHead(200, headers);
      res.end();
      });

      我不知道 python 语法,但它应该会有所帮助。

      【讨论】:

      • 有趣...现在我得到“无法在将标头发送到客户端后设置标头”。就好像 express 正在设置标头并在从 python 子进程到达回调之前发送它们
      • 尝试在之前添加标题:res.send(JSON.stringify(result));
      • 他们以前。同样的问题。我猜测标头会在某个时间点被发送回客户端,然后在调用回调时,它会将数据发回。由于它们是延迟,因此客户端会刷新。但我仍然不知道为什么我会收到标题消息...
      • 您也可以添加 1 个“选项”请求吗?我已经编辑了我的答案。
      • Since their is a delay, the client refreshes. - 这是一个非常奇怪的说法
      猜你喜欢
      • 2011-07-04
      • 2023-01-26
      • 2021-12-18
      • 1970-01-01
      • 2019-02-06
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 1970-01-01
      相关资源
      最近更新 更多