Загрузить файл с веб-страницы HTML5 на сервер Node.js, используя POST - PullRequest
0 голосов
/ 06 сентября 2018

Dears,

Я хочу реализовать загрузку файлов с использованием сервера на базе HTML5 и Node.js. Также я не хочу использовать тег формы на стороне клиента, и мне нужно отправить дополнительные данные на сервер о информации о файле. Я использую настройку заголовка HTTP, чтобы сервер мог его перехватить.

В настоящее время моя проблема заключается в том, что клиент может загрузить файл на сервер, но на сервере сохранить файл с дополнительными данными, такими как HTTP-заголовок и границы.

Я думаю, что сервер хранит ВСЕ HTTP-запросы со стороны клиента, включая HTTP-заголовок, двоичные данные файла и дополнительное значение, такое как border.

Что я могу сделать для хранения только файловых данных на стороне сервера?

Сервер реализован с использованием модуля 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) Используйте модуль Formidable 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();
});

Спасибо, что прочитали этот вопрос, и я с нетерпением жду вашего ответа.

1 Ответ

0 голосов
/ 06 сентября 2018

Посмотрите на 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
})
...