首页 > 解决方案 > 创建与 FormData 一起使用的可读流

问题描述

我正在使用API 上传 CSV 文件request我从字符串在内存中创建 CSV 文件并使用模块上传它。但是,我无法从字符串创建可读流。我遵循了关于如何从 Node.Js 中的字符串创建流的 SO 答案。这是我的解决方案代码:

var importResponse = function(csv, callback){
    stringify(csv, function(err, output){

        const s = new Readable();
        s._read = () => {}; 
        s.push(output);
        s.push(null);

        request.post({
          headers: {'X-API-TOKEN':token, 'content-type' : 'multipart/form-data'},
          url: 'https://ca1.qualtrics.com/API/v3/responseimports',
          formData: {
            surveyId: 'SV_123',
            file: {
                value: s,
                options: {
                    contentType: 'text/csv; charset=utf-8'
                }
            }
          }
        }, function(err, res, body){
            if(err || res.statusCode !== 200){
              console.log(err || "Error status code: " + res.statusCode);
              console.log(body);
              return;
            }
        });
    });

}

csv变量看起来像[["QID1","QID2"],["1","2"]],stringify 的输出看起来像"QID1,QID2\n,1,2\n".

这个解决方案给了我错误Unexpected end of input

{"meta":{"httpStatus":"400 - Bad Request","error":{"errorMessage":"Unexpected end of input"}}}

如果我改为使用memfs,它可以正常工作

const fs = require('memfs');

var importResponse = function(csv, callback){
    stringify(csv, function(err, output){
        // Create file in memory
        fs.writeFileSync('/data.csv', output); 

        request.post({
          headers: {'X-API-TOKEN':token, 'content-type' : 'multipart/form-data'},
          url: 'https://ca1.qualtrics.com/API/v3/responseimports',
          formData: {
            surveyId: 'SV_123',
            file: {
                value: fs.createReadStream('/data.csv'),
                options: {
                    contentType: 'text/csv; charset=utf-8'
                }
            }
          }
        }, function(err, res, body){
            if(err || res.statusCode !== 200){
              console.log(err || "Error status code: " + res.statusCode);
              console.log(body);
              return;
            }
        });
    });

}

如何将输出转换为stringify可用于通过 api 上传的 Stream?

标签: javascriptnode.js

解决方案


看起来您正在使用该request库。您可能会遇到他们自述文件中记录的这个警告:

// Pass optional meta-data with an 'options' object with style: {value: DATA, options: OPTIONS}
// Use case: for some types of streams, you'll need to provide "file"-related information manually.
// See the `form-data` README for more information about options: https://github.com/form-data/form-data
custom_file: {
  value:  fs.createReadStream('/dev/urandom'),
  options: {
    filename: 'topsecret.jpg',
    contentType: 'image/jpeg'
  }
}

由于您使用的是非文件流,因此只需提供一个虚拟文件名即可:

request.post({
  headers: {'X-API-TOKEN':token, 'content-type' : 'multipart/form-data'},
  url: 'https://ca1.qualtrics.com/API/v3/responseimports',
  formData: {
    surveyId: 'SV_123',
    file: {
      value: s,
      options: {
        contentType: 'text/csv; charset=utf-8',
        filename: 'dummy.csv'
      }
    }
  }
}, function(err, res, body){
  if(err || res.statusCode !== 200){
    console.log(err || "Error status code: " + res.statusCode);
    console.log(body);
    return;
  }
});

推荐阅读