当前位置: 首页 > 面试题库 >

如何从node.js上传文件

罗俭
2023-03-14
问题内容

当我查询此问题时,发现了很多帖子,但是它们都涉及如何从浏览器将文件上传到node.js服务器。我想将文件从node.js代码上传到另一台服务器。我试图基于对node.js的有限了解来编写它,但是它不起作用。

function (data) {
  var reqdata = 'file='+data;
  var request = http.request({
    host : HOST_NAME,
    port : HOST_PORT,
    path : PATH,
    method : 'POST',
    headers : {
      'Content-Type' : 'multipart/form-data',
      'Content-Length' : reqdata.length
    }
  }, function (response) {
      var data = '';
      response.on('data', function(chunk) {
        data += chunk.toString();
      });
      response.on('end', function() {
        console.log(data);
      });
    });

  request.write(reqdata+'\r\n\r\n');
  request.end();
})

上面的函数被其他生成数据的代码调用。

我尝试使用curl -F“ file = @
”上传相同的数据文件,并且上传成功。但是我的代码失败了。服务器返回一个特定于应用程序的错误,提示上载的文件无效/损坏。

我收集了tcpdump数据并在Wireshark中进行了分析。我的node.js代码发送的数据包缺少多部分数据所需的边界。我在Wireshark数据包中看到此消息

The multipart dissector could not find the required boundary parameter.

知道如何在node.js代码中完成此操作吗?


问题答案:

分段很复杂,如果要使其看起来像客户端通常如何处理“分段/表单数据”,则必须做一些事情。首先,您必须选择一个边界键,这通常是一个随机字符串来标记各个部分的开始和结束(在这种情况下,由于您要发送单个文件,因此它只是一个部分)。每个部分(或一个部分)都将需要一个标头(由边界键初始化),设置内容类型,表单字段的名称和传输编码。零件完成后,您需要使用边界键标记每个零件的末端。

我从来没有从事过multipart的工作,但是我认为这是可以做到的。如果我错了,请有人纠正我:

var boundaryKey = Math.random().toString(16); // random string
request.setHeader('Content-Type', 'multipart/form-data; boundary="'+boundaryKey+'"');
// the header for the one and only part (need to use CRLF here)
request.write( 
  '--' + boundaryKey + '\r\n'
  // use your file's mime type here, if known
  + 'Content-Type: application/octet-stream\r\n' 
  // "name" is the name of the form field
  // "filename" is the name of the original file
  + 'Content-Disposition: form-data; name="my_file"; filename="my_file.bin"\r\n'
  + 'Content-Transfer-Encoding: binary\r\n\r\n' 
);
fs.createReadStream('./my_file.bin', { bufferSize: 4 * 1024 })
  // set "end" to false in the options so .end() isnt called on the request
  .pipe(request, { end: false }) // maybe write directly to the socket here?
  .on('end', function() {
    // mark the end of the one and only part
    request.end('--' + boundaryKey + '--'); 
  });

再说一次,我以前从未做过,但是我 认为 这是可以实现的。也许知识渊博的人可以提供更多的见解。

如果要以base64或原始二进制文件以外的其他编码形式发送它,则必须自己进行所有管道传递。最终将变得更加复杂,因为您将不得不暂停读取流并等待请求中的流失事件,以确保您不会耗尽所有内存(如果它不是一个大文件,通常不必为此担心)。
编辑: 实际上,没关系,您 可以 在读取流选项中设置编码。

如果还没有Node模块已经做到这一点,我会感到惊讶。也许有人对此主题有更深入的了解可以为您提供一些底层的细节方面的帮助,但是我认为应该在某个地方有一个模块来执行此操作。



 类似资料:
  • 我看的是: > 与谷歌云平台集成 当前代码:

  • 本文向大家介绍Node.js实现文件上传,包括了Node.js实现文件上传的使用技巧和注意事项,需要的朋友参考一下 在工作中碰到了这样的需求,需要用nodejs 来上传文件,之前也只是知道怎么通过浏览器来上传文件, 用nodejs的话, 相当于模拟浏览器的行为。 google 了一番之后, 明白了浏览器无非就是利用http协议来给服务器传输数据, 具体协议就是《RFC 1867 - Form-ba

  • 问题内容: 看来这应该是一个相当简单的问题,但是我很难确定如何解决它。 我正在使用Node.js + Express构建一个Web应用程序,并且发现表达暴露的connect BodyParser在大多数情况下非常有用。但是,我想对多部分表单数据POSTS进行更细粒度的访问- 我需要将输入流通过管道传输到另一台服务器,并且希望避免先下载整个文件。 但是,由于我使用的是Express BodyPars

  • 问题内容: 我正在使用Flash录制音频并将其上传到节点服务器。Flash客户端是jrecorder的变体。当用户完成录制后,将使用POST请求(而不是表单,因为Flash无法创建文件)来上传音频,并将音频ByteArray作为POST请求的数据(请参见此处的更多信息)。 我可以使用下面的代码在Node- land上正确接收文件,但是发出的音频被破坏了,您听不到任何声音。话虽如此,该文件的内容可以

  • 问题内容: 我使用了以下代码,图像已被删除,但缩略图仍然显示。 问题答案: 要删除缩略图,您必须启用addRemoveLinks:true,并在dropzonejs中使用“ removedfile”选项 removefile:每当从列表中删除文件时调用。您可以听一下,并根据需要从服务器中删除文件。 我还添加了一个ajax调用,用于删除脚本,它看起来像这样: 它对我有效,因此希望对您有所帮助。

  • 问题内容: 我已经使用以下代码: fileupload.html fileupload.js: 我已经使用以上这些代码进行文件上传,但是在终端中使用节点fileupload.js执行时,出现类型错误 任何人都可以帮助解决此问题。 问题答案: 您正在尝试使用的旧API。它改变了一段时间,请参阅文档以获取更多信息。 在您上载单个文件的特定情况下,您将删除该行,而使用和一样: