无法发送文件到 expressmulter 后台。

问题描述 投票:0回答:1

我有以下代码,列出文件夹中的文件。然后试图将它们发送到快递后台的postupload中。但文件总是未定义。然而似乎大小和其他信息都能通过。

客户端发送

const axios = require('axios');
var FormData = require('form-data');

//requiring path and fs modules
const path = require('path');
const fs = require('fs');
//joining path of directory 
const directoryPath = path.join(__dirname, '');
//passsing directoryPath and callback function
fs.readdir(directoryPath, function (err, files) {
    //handling error
    if (err) {
        return console.log('Unable to scan directory: ' + err);
    } 
    //listing all files using forEach
    var postInfo = files.forEach(async function (file) {

        const form_data = new FormData();
        form_data.append('file', fs.createReadStream(file));
        const request_config = {
            method: "post",
            url: 'http://localhost:8080/upload',
            port: 8080,
            headers: {
                "Content-Type": "multipart/form-data; boundary=form_data._boundary"
            },
            data: form_data
          };
        try {
            var req = await axios(request_config);
            // Do whatever you want to do with the file
            console.log("Request: ", req); 

        } catch (e) {
            console.error(e);
        }
    });
    console.log(postInfo);
});

后台接收代码

const http = require('http')
const port = 8080
const express = require('express');
const app = express();
const multer = require('multer');
const server = http.createServer(app)

let storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, './uploads')
    },
    filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
    }
});

const upload = multer({ storage }).single('file');


app.post('/upload', upload, (req, res) => {
    console.log(req.files) // this does log the uploaded image data.
})

// bind the server on port
server.listen(port, (err) => {
    if (err) {
        return console.log('something bad happened', err)
    }
    console.log(`server is listening on ${port}`)
})

日志。

node file-receive.js 
server is listening on 8080
undefined
undefined
undefined

  response: undefined,
  isAxiosError: true,
  toJSON: [Function] }
{ Error: socket hang up
    at createHangUpError (_http_client.js:323:15)
    at Socket.socketOnEnd (_http_client.js:426:23)
    at Socket.emit (events.js:194:15)
    at endReadableNT (_stream_readable.js:1103:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)
  code: 'ECONNRESET',
  config:
   { url: 'http://localhost:8080/upload',
     method: 'post',
     data:
      FormData {
        _overheadLength: 169,
        _valueLength: 0,
        _valuesToMeasure: [Array],
        writable: false,
        readable: true,
        dataSize: 0,
        maxDataSize: 2097152,
        pauseStreams: true,
        _released: true,
        _streams: [],
        _currentStream: null,
        _insideLoop: false,
        _pendingNext: false,
        _boundary: '--------------------------046964089061111513973474',
        _events: [Object],
        _eventsCount: 1 },
     headers:
      { Accept: 'application/json, text/plain, */*',
        'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'axios/0.19.2' },
     transformRequest: [ [Function: transformRequest] ],
     transformResponse: [ [Function: transformResponse] ],
     timeout: 0,
     adapter: [Function: httpAdapter],
     xsrfCookieName: 'XSRF-TOKEN',
     xsrfHeaderName: 'X-XSRF-TOKEN',
     maxContentLength: -1,
     validateStatus: [Function: validateStatus],
     port: 8080 },
  request:
   Writable {
     _writableState:
      WritableState {
        objectMode: false,
        highWaterMark: 16384,
        finalCalled: false,
        needDrain: false,
        ending: false,
        ended: false,
        finished: false,
        destroyed: false,
        decodeStrings: true,
        defaultEncoding: 'utf8',
        length: 0,
        writing: false,
        corked: 0,
        sync: true,
        bufferProcessing: false,
        onwrite: [Function: bound onwrite],
        writecb: null,
        writelen: 0,
        bufferedRequest: null,
        lastBufferedRequest: null,
        pendingcb: 0,
        prefinished: false,
        errorEmitted: false,
        emitClose: true,
        bufferedRequestCount: 0,
        corkedRequestsFree: [Object] },
     writable: true,
     _events:
      [Object: null prototype] {
        response: [Function: handleResponse],
        error: [Function: handleRequestError] },
     _eventsCount: 2,
     _maxListeners: undefined,
     _options:
      { protocol: 'http:',
        maxRedirects: 21,
        maxBodyLength: 10485760,
        path: '/upload',
        method: 'POST',
        headers: [Object],
        agent: undefined,
        agents: [Object],
        auth: undefined,
        hostname: 'localhost',
        port: '8080',
        nativeProtocols: [Object],
        pathname: '/upload' },
     _redirectCount: 0,
     _redirects: [],
     _requestBodyLength: 983,
     _requestBodyBuffers: [ [Object], [Object], [Object] ],
     _onNativeResponse: [Function],
     _currentRequest:
      ClientRequest {
        _events: [Object],
        _eventsCount: 6,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: true,
        chunkedEncoding: true,
        shouldKeepAlive: false,
        useChunkedEncodingByDefault: true,
        sendDate: false,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: null,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [Socket],
        connection: [Socket],
        _header:
         'POST /upload HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nContent-Type: application/x-www-form-urlencoded\r\nUser-Agent: axios/0.19.2\r\nHost: localhost:8080\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n',
        _onPendingData: [Function: noopPendingOutput],
        agent: [Agent],
        socketPath: undefined,
        timeout: undefined,
        method: 'POST',
        path: '/upload',
        _ended: false,
        res: null,
        aborted: undefined,
        timeoutCb: null,
        upgradeOrConnect: false,
        parser: null,
        maxHeadersCount: null,
        _redirectable: [Circular],
        [Symbol(isCorked)]: false,
        [Symbol(outHeadersKey)]: [Object] },
     _currentUrl: 'http://localhost:8080/upload' },
  response: undefined,
  isAxiosError: true,
  toJSON: [Function] }
node.js express multer
1个回答
0
投票

我能够重现这个问题,并且能够用下面的ajdustments修复代码(注意我上传的是单个文件,为了简化)。

在客户端,你基本上只需要提供表单数据给axios,然后调用 getHeaders() 来获得已经设置好的头像--你还需要调整一下 file表单中的-名。

// client.js
...
const form_data = new FormData();
form_data.append('file', fs.createReadStream(__dirname + '/file-you-want-to-upload'));

const request_config = {
     method: "post",
     url: 'http://localhost:8080/upload',
     port: 8080,
     data: form_data,
     headers: form_data.getHeaders()
    }; 
...

在后端,你需要确保访问 filefiles 因为你使用 upload.single 并在你的处理程序中实际发送一个响应,否则resposse会挂起。

//server.js
...
const upload = multer({storage}).single('file');
app.post('/upload', upload, (req, res) => {
    console.log(req.file) // this does log the uploaded image data.
    res.send("File uploaded");
});
...
© www.soinside.com 2019 - 2024. All rights reserved.