node做http client 发送post数据是很容易的事情,但要上传文件就不是太容易了
主要是因为上传文件的报文和普通post是不太一样的

要了解http post可以看下这个 https://imququ.com/post/four-ways-to-post-data-in-http.html

npm上封装好的第三方库很多 比如request,我们来看下自己实现需要怎么做

首先要声称个随机串,这个是用来做分段的标记
var boundaryKey = Math.random().toString(16)

上传文件时要设置请求头 Content-Type : 'multipart/form-data; boundary='+boundaryKey+''

报文格式是这样的:

假如 boundaryKey=AaB03x

Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="submit-name" Larry
--AaB03x
Content-Disposition: form-data; name="files"; filename="file1.txt"
Content-Type: text/plain ... contents of file1.txt ...
--AaB03x--

from https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2

每个字段用 “--”+分割符号 分段

结尾用 “--”+分割符号+“--” 注意用\r\n换行 不可缺少

代码实现

 var http = require('http')
var fs = require('fs')
var querystring = require('querystring')
var path = require('path')
var util = require('util') var boundaryKey = Math.random().toString(); // random string
var reqdata = {
  'abc' : ''
} var request = http.request({
  host : 'abc.com',
  port : ,
  path : '/abc',
  method : 'POST'
}, function (response) {
  var data = '';
  response.on('data', function(chunk) {
    data += chunk.toString();
  });
  response.on('end', function() {
    console.log(data);
  });
}); var enddata = '\r\n--' + boundaryKey + '--';
function mkfield (field, value) {
  return util.format('Content-Disposition: form-data; name="%s"\r\n\r\n%s', field, value);
}
var payload = '--' + boundaryKey + '\r\n'
for (var name in reqdata){
  payload += mkfield(name ,reqdata[name]) + util.format('\r\n--%s\r\n', boundaryKey)
}
payload += 'Content-Disposition:form-data; name="img"; filename="image.jpg"\r\n'
  + 'Content-Type:image/jpeg\r\n'
  + 'Content-Transfer-Encoding: binary\r\n'
  + '\r\n'; request.setHeader('Content-Type', 'multipart/form-data; boundary='+boundaryKey+'');
//request.setHeader('Content-Length', Buffer.byteLength(payload)+Buffer.byteLength(enddata)) request.write(payload ) fs.createReadStream('文件路径', { bufferSize: * })
.on('end', function() {
//报文结束
  request.end(enddata);
}).pipe(request, { end: false })
05-11 17:50