Res.download()使用html表单提交而不是Axios帖子调用 [英] Res.download() working with html form submit but not an Axios post call

查看:92
本文介绍了Res.download()使用html表单提交而不是Axios帖子调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个小型应用程序,该应用程序将来自React应用程序的信息提交到Express服务器的"/下载" API,然后在其中将新文件写入本地文件系统,并使用Express在客户端下载新创建的文件fs.writeFile()回调中的res.download().

I am writing a small app that submits information from a React app to an Express server's "/download" API where it then writes a new file to the local file system and downloads the newly created file on the client side using the Express res.download() in the fs.writeFile() callback.

我一直在使用常规的html表单提交来发布数据,但是由于复杂性的增加,我已经使用Axios进行了切换,并且它不再起作用.

I've been using a regular html form submit to post the data but due to an increase in complexity I've switched over using Axios and it's no longer working.

奇怪的是,只有客户端上的下载似乎已停止工作.写入文件就可以了,所有控制台日志记录都是相同的(下面的文件已下载!"日志).当我切换回表单提交时,它继续起作用,因此唯一的更改是使用Axios发送发帖请求.据我所知,一旦数据到达那里,两者之间就应该没有任何区别,但是我希望有人对此比我有更深入的了解.

The strange thing is only the download on the client side seems to have stopped working. Writing the file works just fine, all the console logging is the same ("File downloaded!" logs below). When I switch back to the form submit it continues to work so the only change is using Axios to send the post request. As far as I'm aware there shouldn't be any difference between the two once the data gets there but I'm hoping someone has greater insight into this than I.

除了在表单和Axios发布请求之间进行测试外,我还尝试将Axios请求的内容类型从"application/json"更改为"x-www-form-urlencoded",以为匹配内容输入表单发送的内容可能就是答案

In addition to testing between form and Axios post requests I've also tried changing the content-type of the Axios request to be "x-www-form-urlencoded" from "application/json" thinking that matching up the content type to what the form was sending might be the answer

以下是相关应用的相关代码段:

The below is the relevant code snippets from the app in question:

app.post('/download', (req, res) => {
  console.log("Requst data");
  console.log(req.body.html);


  fs.writeFile("./dist/test.txt", res.body.test,
    (err) => {
      if(err) {
        return console.log(err);
      } else{
        console.log("The file was saved!");
      }

      let file = __dirname + '/text.txt';
      /*This is the issue, the file is not downloading client side for the Axios iteration below*/
      res.download(file,(err)=>{
        if(err){
          console.log(err);
        } else {
          console.log(file);
          /*This logs for both View.js iterations below*/
          console.log("File downloaded!");
        }
      });
    });
})

App.js(反应)

handleSubmit(e){
    e.preventDefault();

    axios.post(`/download`, {test: "test"})
      .then(res => {
        console.log("REQUEST SENT");
      })
      .catch((error) => {
        console.log(error);
      });
}

render(){
      return(
        <div>
          <View handleSubmit={this.handleSubmit} />
        </div>
      )
}

View.js(反应)

这有效:

View.js (React)

This works:

render(){
      return(
        <form action="/download" method="post">
            <input type="submit">
        </form>
      )
}

不会在客户端上启动下载,但其他方法也可以:

This doesn't initiate the download on the client side, but otherwise works just fine:

render(){
      return(
        <form onSubmit={this.props.handleSubmit}>
            <input type="submit">
        </form>
      )
}

我没有收到任何错误,除了客户端上的下载以外,其他所有内容似乎都正常运行.

I'm not getting any error, everything seems to be working properly except the download on the client side.

预期结果是使用Axios在客户端下载了文件,但事实并非如此.

The expected result is that the file downloads on the client side using Axios but that's not the case.

更新:颠簸,对此没有任何吸引力

Update: Bump, not getting any traction on this

推荐答案

实际上,您可以通过一些Blob操作在Ajax POST请求中下载文件.下面列出了示例代码,并附有注释说明:

Actually, you CAN download file in Ajax POST request, with some blob operation. Example code is listed below, with explanation comment:

handleSubmit(e){
  var req = new XMLHttpRequest();
  req.open('POST', '/download', true); // Open an async AJAX request.
  req.setRequestHeader('Content-Type', 'application/json'); // Send JSON due to the {test: "test"} in question
  req.responseType = 'blob'; // Define the expected data as blob
  req.onreadystatechange = function () {
    if (req.readyState === 4) {
      if (req.status === 200) { // When data is received successfully
        var data = req.response;
        var defaultFilename = 'default.pdf';
        // Or, you can get filename sent from backend through req.getResponseHeader('Content-Disposition')
        if (typeof window.navigator.msSaveBlob === 'function') {
          // If it is IE that support download blob directly.
          window.navigator.msSaveBlob(data, defaultFilename);
        } else {
          var blob = data;
          var link = document.createElement('a');
          link.href = window.URL.createObjectURL(blob);
          link.download = defaultFilename;

          document.body.appendChild(link);

          link.click(); // create an <a> element and simulate the click operation.
        }
      }
    }
  };
  req.send(JSON.stringify({test: 'test'}));
}

对于后端,没有什么特别的,只是一个简单的res.download语句:

For backend, there is nothing special, just a plain res.download statement:

app.post('/download', function(req, res) {
  res.download('./example.pdf');
});

对于axios,前端代码如下:

For axios, the frontend code would look like:

axios.post(`/download`, {test: "test"}, {responseType: 'blob'})
  .then(function(res) {
        ...
        var data = new Blob([res.data]);
        if (typeof window.navigator.msSaveBlob === 'function') {
          // If it is IE that support download blob directly.
          window.navigator.msSaveBlob(data, defaultFilename);
        } else {
          var blob = data;
          var link = document.createElement('a');
          link.href = window.URL.createObjectURL(blob);
          link.download = defaultFilename;

          document.body.appendChild(link);

          link.click(); // create an <a> element and simulate the click operation.
        }
  })
  .catch((error) => {
    console.log(error);
  });

这篇关于Res.download()使用html表单提交而不是Axios帖子调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆