【问题标题】:Nodejs save JSON fileNodejs保存JSON文件
【发布时间】:2019-09-15 17:09:46
【问题描述】:
  1. 说我有这个<input type="file" id="theFile">

  2. 我使用 myVar = document.getElementById('theFile').value 访问所选文件

  3. 输出为console.log(myVar); // C:\fakepath\xxx.txt

然后我做一个简单的 POST,做一个 POST 的方法有很多,但一个基本的 JavaScript 方法是:

var http = new XMLHttpRequest();
http.onreadystatechange = function() { 
http.open("POST", "http://localhost:port/upload-test");
http.setRequestHeader('Content-type', 'application/json');
var body = {
    file: document.getElementById('theFile').value
}
http.send(JSON.stringify(body));

然后在我的Nodejs Express 服务中我这样做:

app.post('/upload-test', (request, response) => {
    console.log(request.body); // { file: 'C:\\fakepath\\xxx.txt' }
});

现在如何将该文件保存到运行服务的电脑上?

我知道其他解决方案,例如https://www.w3schools.com/nodejs/nodejs_uploadfiles.asp,但这需要用户使用<form>,这不是我想要的。我想使用基本的 POST 和 JSON 方法上传文件。

【问题讨论】:

  • 你实际上并没有发送文件,只是它的路径,服务器端不能对它做任何事情,因为它无法访问客户端的文件系统。如果您想避免使用表单,可以使用formData 并附加文件,如this answer
  • 我已经这样做了,但不是您尝试的方式。首先,您需要将客户端文件的内容“读取”到一个 var 中,然后像您所做的那样使用 JSON.stringify。在服务器上,然后使用 fs 包创建一个新的空文件并将文件内容“流式传输”到文件并保存。
  • @ChrisAdams 你能举个例子吗?这种方法是否适用于任何文件类型(不仅仅是txt)?
  • 我可以试试,是的,它应该适用于任何文件类型。

标签: node.js


【解决方案1】:

请求的内容类型应该是multipart/form-data,因为您正在上传文件。 您可以使用 multerjs 进行 nodejs 上传

var express = require('express')
var multer  = require('multer')
var upload = multer({ dest: 'uploads/' })

var app = express()

app.post('/upload-test', upload.single('avatar'), function (req, res, next) {
  // req.file is the `avatar` file
  // req.body will hold the text fields, if there were any
})

【讨论】:

    【解决方案2】:

    客户端 首先,您需要将文件内容“读取”到变量中。您不能直接上传文件,如此处其他地方所述。

    我不确定您使用的是什么客户端。例如。 React、Angular 或纯 Javascript。因此,这里有一个关于 SO 的另一篇文章的链接,该文章介绍了如何选择客户端文件并将其内容读入 var。 Read Client-Side file

    在 var 中获得文件内容后,您可以“发布”它。例如

    // Build the Headers object.
    let headers = new Headers();
    headers.append("Content-Type","application/json");
    
    // Build the body object.
    let body = {
        fileName: varContainingFileName,
        fileContent: varContianingContentsOfFile
    };
    
    // Build the request
    const response = await fetch(URL, {method: 'POST',
                                        headers:headers, 
                                        body:JSON.stringify(body)});
    
    // See what we get back from the service.  Note, for the await to work,
    // Needs to be wrapped in async method.
    console.log(response);
    

    服务器端 我假设你已经为 API 设置了路由,所以直接进入......

    const fs = require('fs');
    
    uploadFile(req, res) {
    
        const requestBody = JSON.parse(req.body);
    
        log.info("Received File Upload request.  File " + requestBody.fileName);
    
        // If one doesn't exist, create a folder for the file
        fs.existsSync("./SomeFolder/") || fs.mkdirSync("./SomeFolder/");
    
        // Using method.then(otherMethod) with promises.
        writeSourceDataToFile (requestBody.fileName,
                                "./SomeFolder/",
                                requestBody.fileContent)
          .then(v => finalMethod(v, requestBody.fileName, "./SomeFolder/", res))
          .catch(err => returnError(res, err) );
    
    }
    
    function writeSourceDataToFile (fileName, path, content) {
    
        return new Promise((resolve, reject) => {
    
            // User fs write stream to stream the file content var to file.
            let writeSource = fs.createWriteStream(path + fileName)
                .on('end', function () {
                    log.info("File wrote to disk - End event");
                    resolve (true);
                })
               .on('finish', function () {
                   log.info("File wrote to disk - Finish event");
                   resolve (true);
                })
               .on('error', function (err) {
                   log.info('Error whilst writing file - ' + fileName);
                   reject (err);
               });
    
            writeSource.write(content);
    
            writeSource.end();
    
        });
    }
    
    function finalMethod(v, fileName, path, res) {
    
        // Final method just wraps things up and sends some message back to 
        // client.
    
        log.info(fileName + " File Upload Process Completed.");
        res.write("File Upload Process Completed.\n");
    
        res.status(200).end();
    
    }
    
    // Something went wrong, log it and tell the client.
    function returnError(res, err) {
      log.error(err);
      res.status(500).send(err);
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用 Multer 模块进行文件上传

      const multer = require('multer');
      

      现在设置destinatoin文件夹来保存上传的文件

      const upload = multer({ dest: './uploads/' });
      

      最后使用upload.single() 上传单个文件或使用upload.array() 上传多个文件

      app.post('/upload-test',upload.single('myFile'),(request, response) => {
          console.log(request.body);
      });
      

      【讨论】:

        猜你喜欢
        • 2015-05-21
        • 2019-08-02
        • 2020-12-26
        • 2016-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-18
        相关资源
        最近更新 更多