【问题标题】:Upload file from HTML5 web page to Node.js server using POST使用 POST 将文件从 HTML5 网页上传到 Node.js 服务器
【发布时间】:2018-09-06 00:51:21
【问题描述】:

亲爱的,

我想使用基于 HTML5 和 Node.js 的服务器来实现文件上传网页。 另外我不想在客户端使用表单标签,我需要向服务器发送有关文件信息的额外数据。我使用自定义 HTTP 标头,以便服务器可以捕获它。

目前我的问题是客户端可以将文件上传到服务器,但服务器保存的文件带有附加数据,例如 HTTP 标头和边界。

我认为服务器存储来自客户端的所有 HTTP 请求包括 HTTP 标头、文件二进制数据和边界等附加值。

如何在服务器端只存储文件数据?

服务器是使用HTTP模块实现的,目前我不能更改服务器的主模块,因为很多东西已经在服务器端实现了。

客户端:

// HTML Code
<tr>
    <td><textarea id="customData1"></textarea></td>
    <td><textarea id="customData2"></textarea></td>
    <td><input type="file" id="uploadFile"></td>
    <td><button id="uploadFile" onclick="uploadFileToServer()">Upload</button</td>
</tr>

// JavaScript Code
function uploadFileToServer() {
    var file = document.getElementById("uploadFile").files[0];
    var uri = "/uploadFile";
    var xhr = new XMLHttpRequest();
    var fd = new FormData();

    xhr.open("POST", uri, true);

    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            alert(xhr.responseText);
        }
    };

    xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=\\\"Boundary\\\"");

    xhr.setRequestHeader("my-custom-data-one", document.getElementById("customData1").value);
    xhr.setRequestHeader("my-custom-data-two", document.getElementById("customData2").value);
    xhr.setRequestHeader("file-size", file.size);
    xhr.setRequestHeader("file-name", file.name);

    fd.append("myFile", file);
    xhr.send(fd);
}
</script>

我尝试了一些方法,但都不起作用。

服务器端:

基本服务器代码)

http.createServer(function (req, res) {
    if (req.method === 'POST') {
        // Need to add upload file code
    }
}).listen(PORT.Main);

案例 1) 使用附加块数据。但也写入了无用的数据(标题/边界)。

 req.on('data', function (data) {
     console.log(data)
     fs.appendFileSync(filename, data)// += data;

 });

 req.on('end', function () {
     res.writeHead(200, { 'content-type': 'text/plain' })
     res.write('Upload Complete!\n');
     res.end();
 });

案例 2) 使用 writeStream。但也写入了无用的数据(标题/边界)。

var file = './temp.file'
var downloadWriteStream = fs.createWriteStream(file);
req.pipe(downloadWriteStream);
req.on('end', function () {
    res.writeHead(200, { 'content-type': 'text/plain' })
    res.write('Upload Complete!\n');
    res.end();
});

案例3)使用强大的npm模块,但它返回错误消息:错误:MultipartParser.end():流意外结束:状态= START_BOUNDARY

var form = new formidable.IncomingForm();

form.parse(req);

form.on('fileBegin', function (name, file) {
    file.path = filename;
});

form.on('file', function (name, file) {
    console.log('Uploaded ' + file.name);

    res.writeHead(200, { 'content-type': 'text/plain' })
    res.write('Upload Complete!\n');
    res.end();
});

感谢您阅读此问题,期待您的回答。

【问题讨论】:

  • 请忽略 \\\"Boundary\\\""。原来所有的 HTML 代码都是来自服务器的字符串值(不是来自 HTML 文件)。所以这只是错字。

标签: node.js html formidable


【解决方案1】:

看看multer。这让这变得超级简单。

客户端示例代码:

<form action="/profile" method="post" enctype="multipart/form-data">
  <input type="file" name="avatar" />
</form>

服务器示例代码:

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

var app = express()

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

【讨论】:

  • 感谢您的回答。我尝试使用 express-formiable 从网页获取更多数据,但如果我使用 mutler 和 express-formiable,则 multer 不起作用。我如何同时使用它?
猜你喜欢
  • 2013-12-14
  • 2012-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-31
  • 2022-06-22
  • 2014-09-21
相关资源
最近更新 更多