Search code examples
node.jsexpresssingle-page-applicationfeathersjs

Using connect-history-api-fallback middleware in FeathersJS for serving Vue.js SPA


As the title suggests, I'm serving a Vue.js single page application from public/index.html in FeathersJS. Since I'm using vue-router's HTML5 history mode, I have to use a middleware like connect-history-api-fallback in order to rewrite the requested frontend location to /index.html.

Setting up this middleware in src/middleware just before app.use(notFound()); doesn't work since Feathers serves the static files before everything else, so by the time the request gets rewritten nothing picks up /index.html and notFound serves a 404 response.

Configuring it before .use('/', serveStatic(app.get('public'))) inside src/app.js is also problematic since it will rewrite every service request to /index.html, making API calls unreachable.

I ended up moving the serveStatic middleware after .configure(services) and placing connect-history-api-fallback right above like so:

app.use(compress())
  .options('*', cors())
  .use(cors())
  // favicon and serveStatic used to be here
  .use(bodyParser.json())
  .use(bodyParser.urlencoded({ extended: true }))
  .configure(hooks())
  .configure(rest())
  .configure(socketio())
  .configure(services)
  .use(require('connect-history-api-fallback')())
  // now they are down here
  .use(favicon(path.join(app.get('public'), 'favicon.ico')))
  .use('/', serveStatic(app.get('public')))
  .configure(middleware);

My question is the following: Are there any performance or security drawbacks to this approach?


Solution

  • With the configuration you posted, there aren't really any security concerns.

    If you were to replace your serveStatic middleware with SSR middleware, you would want to delete the CORS headers before the SSR middleware to avoid leaking data through Cross Site Requests (CSRF "attacks" using cookies).