express配置单页应用路由

之前有个项目是用的react,构建完生成的静态文件给后端看的时候写的node+express的web服务器,发现页面刷新404的问题,由于SPA基本上都是是用history API实现的路由,从index进去后的跳转不受影响,但是单独请求某个地址会使用路径去找相应资源结果404,实际上需要所有地址都返回index.html

想着一个一个路径配置路由感觉有点麻烦,在网上搜了一下,可以使用这个中间件connect-history-api-fallback

Middleware to proxy requests through a specified index page, useful for Single Page Applications that utilise the HTML5 History API.

npm install --save connect-history-api-fallback
const express = require('express');
const history = require('connect-history-api-fallback');

const app = express();

app.use('/', history());
app.use(express.static('./dist')); // 文件在dist目录下

app.listen(8077);

如果页面不是index.html可以配置参数

history({index: '/xxx.html'})

大概是判断get请求(以及req.headers中的accept),如果不是请求css或js(判断的./的位置),也没有单独设置rewrite的,就都会返回index设置的路径

const url = require('url');
// ...先过滤掉一部分
let headers = req.headers;
    if (req.method !== 'GET') {
      return next();
    } else if (!headers || typeof headers.accept !== 'string') {
      return next();
    } else if (headers.accept.indexOf('application/json') === 0) {
      return next();
    } else if (!acceptsHtml(headers.accept, options)) {
      return next();
    }

function acceptsHtml(header, options) {
  options.htmlAcceptHeaders = options.htmlAcceptHeaders || ['text/html', '*/*'];
  for (let i = 0; i < options.htmlAcceptHeaders.length; i++) {
    if (header.indexOf(options.htmlAcceptHeaders[i]) !== -1) {
      return true;
    }
  }
  return false;
}
// ... 有类似.js .css等的资源
let pathname = url.parse(req.url).pathname;
if (pathname.lastIndexOf('.') > pathname.lastIndexOf('/') &&
      options.disableDotRule !== true) {
      logger(
        'Not rewriting',
        req.method,
        req.url,
        'because the path includes a dot (.) character.'
      );
      return next();
    }

// ... rewrite到index
    req.url = options.index || '/index.html';
Comments
Write a Comment