nodejs (koa): невозможно установить заголовки после их отправки

У меня есть программа, которая хочет сопоставить /a/b/c.js url => /a:b:c.js файл;

koa version:2.3.0 koa static version: 4.0.1

минимальное воспроизведение

const KOA = require('koa');
const koaStatic = require('koa-static');

staticApp = new KOA()
staticApp.use((ctx, next) => {
  let path = ctx.path.split('/');
  path = path.filter(segment => segment)
  ctx.path = `/${path.join(':')}`;
  next()
})
staticApp.use(koaStatic(__dirname))
staticApp.listen(8888);

Предположим, что в текущем каталоге есть файл a:b:c.js, когда я обращаюсь к locahost:8888\a\b\c.js в браузере, программа всегда получает ошибку UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 4): Error: Can't set headers after they are sent.

спасибо за помощь!


person Qiu    schedule 17.07.2017    source источник


Ответы (2)


Попробуй это:

const KOA = require('koa');
const koaStatic = require('koa-static');

staticApp = new KOA()
staticApp.use((ctx, next) => {
  let path = ctx.path.split('/');
  path = path.filter(segment => segment)
  ctx.path = `/${path.join(':')}`;
  return next();
});
staticApp.use(koaStatic(__dirname));
staticApp.listen(8888);

Кажется, что если вы хотите использовать общую функцию в качестве промежуточного программного обеспечения, вы должны вернуть следующую функцию.

person Yi Kai    schedule 17.07.2017
comment
Знаете ли вы, почему общая функция в качестве промежуточного программного обеспечения должна возвращать следующую функцию? спасибо - person Qiu; 17.07.2017
comment
@Qiu Я думаю, это потому, что вы должны вернуть обещание от своего промежуточного программного обеспечения для работы с другими промежуточными программами. Следующий возврат обещания, когда вы возвращаете его, вы возвращаете обещание. Дополнительные обсуждения см. в этой проблеме github.com/koajs/koa/issues/997. - person Yi Kai; 17.07.2017

Я обнаружил, что для решения этой проблемы мне пришлось отключить промежуточное ПО на некоторых маршрутах. В моем случае это промежуточное программное обеспечениеpassword.js, которое устанавливало файлы cookie, чего я не хотел, чтобы происходило при запросах через путь /proxy. Это мое решение:

const blacklistRoute = (fn, p) => async (ctx, next) => {
  if (ctx.request.path.startsWith(p)) {
    return next()
  } else {
    return fn(ctx, next)
  }
}

const app = ...

app
  .use(
    blacklistRoute(
      koaSession(passportCookieConfig, app),
      '/proxy'
    )
  )
person Zach Smith    schedule 10.02.2021