管道 node.js ServerResponse 对象在强大的事件结束后抛出写入

piped node.js ServerResponse object throws write after end in formidable event

此处未包含 enctype='multipart' 的基本 html 形式。第一次到服务器的服务没有错误,但在通过上传路径两次之后。节点抛出 "write after end Error"。

在事件内部调用 resp.end() 不会产生此错误,并且仅当流管道在强大的事件内部完成时才会发生。

const http = require( "http" );
const form = require( 'formidable' ).IncomingForm();

    function fileStream( filepath){
        let readstream = fs.createReadStream(filepath );
        readstream.setEncoding( "utf8" );
        return readstream;
    }

    let server = http.createServer();
    server.listen( 8080 );

    server.on( "request", function( req, resp ){

        let requestpath = url.parse( req.url ).pathname.slice( 1 );

    switch ( requestpath ) {
            case "upload":
                form.parse( req );
                form.on( "field", function( field ){
   //throws "ERR_STREAM_WRITE_AFTER_END" after 2nd request/upload trip
                    filestream( "index.html").pipe( resp );
                } )
                break;
            default:
                filestream( "index.html").pipe( resp );
                break;
        }
    } )

根据Node.js,通过管道传输到 IncomingMessage 的流将在读取流关闭后调用 end()。我试图了解错误的原因是什么。因为强大似乎没有结束响应。

您需要为每个请求创建一个新的 IncomingForm 实例:

const { IncomingForm } = require('formidable');

...

switch (requestpath) {
  case "upload":
    const form = IncomingForm();
    form.parse(req);
    form.on("field", function(field) {

如果你不这样做,对于每个请求都会发出一个额外的 field 事件(我猜 formidable 通过附加到一些内部缓冲区来内部存储正文数据)。

在第一个 field 事件发出后,您的代码流式传输文件(随后结束响应),第二个 field 事件将尝试执行相同的操作并导致错误发生。