Javascript 创建用于FormData的可读流

Javascript 创建用于FormData的可读流,javascript,node.js,Javascript,Node.js,我用的是一台电脑。我从一个字符串在内存中创建CSV文件,并使用request模块上传它。但是,从字符串创建可读流时遇到问题。我按照这样的答案继续回答。以下是我的解决方案代码: var importResponse = function(csv, callback){ stringify(csv, function(err, output){ const s = new Readable(); s._read = () => {};

我用的是一台电脑。我从一个字符串在内存中创建CSV文件,并使用
request
模块上传它。但是,从字符串创建可读流时遇到问题。我按照这样的答案继续回答。以下是我的解决方案代码:

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”

此解决方案向我提供了错误
输入意外结束

{"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上载的流?

对于当前节点版本,示例代码段不正确或可能已过时。一种非常简单的实现可读性的方法:

const s = new Readable({
  encoding: 'utf8',
  read(size) {
    // Possibly respect the requested size to make for a good consumer experience
    // Otherwise:
    this.push(output, 'utf8');
    this.push(null); // This signals that there's no more data.
  }
});
以下是如何尊重读者的意愿:

let data = output;
const s = new Readable({
  encoding: 'utf8',
  read(size) {
    let wantsMore = true;
    while (wantsMore) {
      const chunk = data.slice(0, size);          
      if (!chunk) {
        return void this.push(null);            
      }

      wantsMore = this.push(chunk, 'utf8');
      data = data.slice(size);
    }
  }
});

看起来您正在使用
请求
库。您可能会遇到以下警告:

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

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;
  }
});

谢谢你的回复。我尝试添加您的代码片段来代替上一个,但仍然收到相同的
意外输入结束
错误。哎呀,我在发送EOF信号时犯了一个错误。尝试我的更新。添加了一些关于编码的注释。这很奇怪。我想我是在注意到你在使用
request
后发现的。“文件”上传很奇怪。查看另一个答案。(暂时保留此选项,以防流也有问题,但它可能是另一个答案)。这样我们就可以确定,
stringify
来自何方?您有需要的特定软件包吗?它看起来像
csv stringify
可以自己创建流,仅供参考。您可以直接将
stringify(csv)
作为“文件”流传递。@Jacob是的,这就解决了它。将我的代码更改为
var output=stringify(csv)现在就可以了。还将stringify模块更改为同步模块。非常感谢。嗨,Jacob,我试着添加文件名(以前有过),但仍然不起作用。我想知道问题是否出在
Stringify
上。我想可能是字符串末尾的新行字符引起的,但事实并非如此。我不确定是
Stringify
memfs
在保存时“修复”了问题,还是流本身是错误的,不一定是内容。。。如果说得通的话。是的,那就是包裹。对不起,我应该说得更清楚。
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;
  }
});