【问题标题】:Piping a stream to request post doesn't work管道流以请求帖子不起作用
【发布时间】:2016-08-18 15:43:00
【问题描述】:

我在request's documentation page 上读到过,可以将文件流式传输到 PUT 或 POST 请求,如下所示:

fs.createReadStream('file.json').pipe(request.put('http://example.com/obj.json'));
request.get('http://google.com/img.png').pipe(request.put('http://example.com/img.png'));    

但它似乎不起作用。我尝试设置一个本地服务器来使用不同的库上传文件。

快递员:

var express = require('express');
var app = express();
var fs = require('fs');
var bb = require('express-busboy');
var app = express();
bb.extend(app, {
    upload: true,
    path: './img/',
    allowedPath: /./
});

app.post('/upload', function(req, res) {
    console.log(req.files);
});

var server = app.listen(process.env.PORT, function() {
    console.log('Listening on port %d', server.address().port);
});

而且强大:

var express = require('express');
var app = express();
var path = require('path');     
var fs = require('fs');     
var formidable = require('formidable');

app.post('/upload', function(req, res){

    // create an incoming form object
    var form = new formidable.IncomingForm();

    // specify that we want to allow the user to upload multiple files in a single request
    form.multiples = true;

    // store all uploads in the /uploads directory
    form.uploadDir = path.join(__dirname, '/img');

    // every time a file has been uploaded successfully,
    // rename it to it's orignal name
    form.on('file', function(field, file) {
        fs.rename(file.path, path.join(form.uploadDir, file.name));
    });

    // log any errors that occur
    form.on('error', function(err) {
        console.log('An error has occured: \n' + err);
    });

   // once all the files have been uploaded, send a response to the client
   form.on('end', function() {
      res.end('success');
   });

  // parse the incoming request containing the form data
  form.parse(req);

});

var server = app.listen(process.env.PORT, function() {
    console.log('Listening on port %d', server.address().port);
});

当我提出这样的请求时,两者都可以正常工作:

var request = require('request');
var fs = require('fs');
var formData = {
      filename: {
      value:  fs.createReadStream('ice.jpg'),
      options: {
        filename: 'ice.jpg',
        contentType: ' image/jpeg'
      }}
  };

request.post({url: 'https://myserver.com/upload', formData: formData});

或者从命令行:

curl -i -X POST -H "Content-Type: multipart/form-data" -F "data=@ice.jpg" https://myserver.com/upload

但是当我尝试这样做时,它们都不起作用:

fs.createReadStream('ice.jpg').pipe(request.post('https://myserver.com/upload'));

我做错了吗?有没有办法让最后一行起作用?

【问题讨论】:

    标签: node.js multipartform-data node-request


    【解决方案1】:

    好的。我正在回答这个问题,以防有人遇到类似的问题。

    Curl 和带有 formData 选项的 request.post 都发送带有 "Content-Type: multipart/form-data" 标头的 post 请求. express-busboyformidablemulter 等库用于解析这些数据。

    这一行:

    fs.createReadStream('ice.jpg').pipe(request.post('https://myserver.com/upload'));
    

    发送带有 "Content-Type: image/jpeg""Transfer-Encoding: chunked" 标头的请求。此处无需解析多部分表单数据。

    服务器上的以下代码将在这种情况下工作:

    var http = require('http');
    var fs = require('fs');
    
    var server = http.createServer(function(req, res){
        console.log(req.headers);
        var body = [];
        req
          .on('data', chunk => {
              body.push(chunk);
              console.log('Chunk ', chunk);
              })
          .on('end', () => {
              body = Buffer.concat(body);
              fs.writeFileSync('newfile.jpg', body, null);
          });
        res.write("OK\n");
        res.end();
    });
    

    【讨论】:

      猜你喜欢
      • 2016-08-18
      • 2015-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多