【问题标题】:Sending Binary File in Express leads to ECONNABORTED在 Express 中发送二进制文件会导致 ECONNABORTED
【发布时间】:2020-07-20 14:15:59
【问题描述】:

我目前正在为后端进行一些测试,但我一直在磕磕绊绊,特别是一项测试有时会通过,有时却不会。如果某些特定标头不存在,则错误发生在我的警卫拒绝请求中。因此,在我的测试中,应用程序看起来与此类似

beforeEach(() => {
    app = express();
    const router = express.Router();
    router.post('/media/upload',      
      addSpies,
      PostMediaGuard(sinon.stub().resolves(true)),
      multer(getMulterOptions()).fields([{ name: 'File', maxCount: 1 }]),
      upload
    ); 

    app.use('/', router);
  });

现在添加间谍只会将间谍添加到我的 req、res 和 next 中,然后继续。该错误发生在我的 PostMediaGuard 中。在这里,我将检查是否存在的标头,如果不存在则拒绝

PostMediaGuard

if(typeof(req.headers['x-some-header']) !== 'string')
      return res.status(400).end('No valid RealmId in Header. Please set X-RealmId');

    if(!await _userMayUploadMediaFile(
      req.headers['x-some-header'],
      req.headers.authorization as string,
      req.user
    ))
      return res.status(403).end(`Not allowed to upload media`);

next();

现在对于我的测试,我将使用 supertest 向我的应用程序发出请求。请求看起来像这样

测试

await request(app)      
        .post('/media/upload')      
        .attach('File', path.join(__dirname, '../../test/media/dummy.jpg'));   

现在,如果我调试一切正常,我将点击行将状态设置为 400 并在 PostMediaGuard 中结束请求。有时在那之后测试会被断言就好了,有时我会用下面的堆栈得到 ECONABORTED

stack:"错误:写入 ECONNABORTED
在 afterWriteDispatched (internal/stream_base_commons.js:150:25)
在 writeGeneric (internal/stream_base_commons.js:141:3)
在 Socket._writeGeneric (net.js:770:11)
在 Socket._write (net.js:782:8)
在 doWrite (_stream_writable.js:431:12)
在 writeOrBuffer (_stream_writable.js:415:5)
在 Socket.Writable.write (_stream_writable.js:305:11)
在 ClientRequest._writeRaw (_http_outgoing.js:295:17)
在 ClientRequest._send (_http_outgoing.js:271:15)
在 ClientRequest.end (_http_outgoing.js:732:10)
在 Transform.onend (_stream_readable.js:691:10)
在 Object.onceWrapper (events.js:299:28)
在 Transform.emit (events.js:210:5)
在 endReadableNT (_stream_readable.js:1183:12)
在 processTicksAndRejections (internal/process/task_queues.js:80:21)"

现在我假设由于请求的表单数据中发送的文件而在后台进行了一些流式传输,并且我试图在完成之前结束请求。但是,我还没有开始任何事情来处理数据,例如创建读取流或尝试将其存储在数据库中。 (因为要注意的是,如果所需的标头不存在,我不会这样做)。到目前为止,我发现的几乎所有关于该主题的答案都是由于一些异步流方法开始并试图在请求完成之前结束请求。但是由于那时我还没有开始那些我不知道我错在哪里

任何想法可能是什么问题?

【问题讨论】:

    标签: node.js express httprequest form-data


    【解决方案1】:

    现在这似乎是 supertest (Issue on GitHub) 的问题

    但是至少有一种解决方法可以通过将连接设置为在标头中保持活动状态来使其工作。

    如果您查看我在问题中的请求示例,请将其更改为类似的内容

    await request(app)      
            .post('/media/upload')      
            .attach('File', path.join(__dirname, '../../test/media/dummy.jpg'))
            .set('Connection', 'keep-alive'); 
    

    现在我仍然无法理解超测会发生什么。 This issue 指出,在表单数据请求中,可能会调用双重回调,因此它可能与此相关。

    到目前为止,我不了解根本原因,但我会在发现后立即在此处更新。至少现在有一种解决方法可以让它工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-04
      • 2015-02-18
      • 2010-12-20
      • 2016-09-17
      • 2014-03-31
      • 2012-07-08
      • 1970-01-01
      相关资源
      最近更新 更多