Uploading a file with node http module

2020-07-27 08:19发布

问题:

How do I upload a file to a remote server with the node http module (and no 3rd party libs)?

I tried the following but it's not working (I get no data on the server):

function writeBinaryPostData(req, filepath) {
    var fs = require('fs');

    var boundaryKey = Math.random().toString(16); // random string
    var boundaryStart = `--${boundaryKey}\r\n`,
        boundaryEnd = `\r\n--${boundaryKey}--`,
        contentDispositionHeader = 'Content-Disposition: form-data; name="file" filename="file.txt"\r\n',
        contentTypeHeader = 'Content-Type: application/octet-stream\r\n',
        transferEncodingHeader = 'Content-Transfer-Encoding: binary\r\n';

    var contentLength = Buffer.byteLength(
        boundaryStart +
        boundaryEnd +
        contentDispositionHeader +
        contentTypeHeader +
        transferEncodingHeader
    ) + fs.statSync(filepath).size;

    var contentLengthHeader = `Content-Length: ${contentLength}\r\n`;

    req.setHeader('Content-Length', contentLength);
    req.setHeader('Content-Type',  'multipart/form-data; boundary=' + boundaryKey);

    req.write(
        boundaryStart +
        contentTypeHeader +
        contentDispositionHeader +
        transferEncodingHeader
    );

    fs.createReadStream(filepath, { bufferSize: 4 * 1024 })
        .on('data', (data) => {
            req.write(data);
        })
        .on('end', () => {
            req.write(boundaryEnd);
            req.end();
        });
}

回答1:

I got it working with the following code:

function writeBinaryPostData(req, filepath) {
    var fs = require('fs'),
        data = fs.readFileSync(filepath);

    var crlf = "\r\n",
        boundaryKey = Math.random().toString(16),
        boundary = `--${boundaryKey}`,
        delimeter = `${crlf}--${boundary}`,
        headers = [
          'Content-Disposition: form-data; name="file"; filename="test.txt"' + crlf
        ],
        closeDelimeter = `${delimeter}--`,
        multipartBody;


    multipartBody = Buffer.concat([
        new Buffer(delimeter + crlf + headers.join('') + crlf),
        data,
        new Buffer(closeDelimeter)]
    );

    req.setHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
    req.setHeader('Content-Length', multipartBody.length);

    req.write(multipartBody);
    req.end();
}

based on code I found here