Authored by 陈峰

解决nodejs history api

@@ -9,7 +9,7 @@ const bodyParser = require('body-parser'); @@ -9,7 +9,7 @@ const bodyParser = require('body-parser');
9 const cookieParser = require('cookie-parser'); 9 const cookieParser = require('cookie-parser');
10 const compression = require('compression'); 10 const compression = require('compression');
11 const Express = require('express'); 11 const Express = require('express');
12 -const history = require('connect-history-api-fallback'); 12 +const history = require('./framework/history-api-fallback');
13 13
14 // const session = require('express-session'); 14 // const session = require('express-session');
15 const cookieSession = require('cookie-session'); 15 const cookieSession = require('cookie-session');
@@ -32,6 +32,7 @@ global.yoho = { @@ -32,6 +32,7 @@ global.yoho = {
32 co: global.Promise.coroutine 32 co: global.Promise.coroutine
33 }; 33 };
34 app.use(history({ 34 app.use(history({
  35 + disableIndex: true,
35 rewrites: [ 36 rewrites: [
36 { from: /\.html/, to: '/index.html'} 37 { from: /\.html/, to: '/index.html'}
37 ] 38 ]
  1 +/* eslint-disable */
  2 +var url = require('url');
  3 +
  4 +exports = module.exports = function historyApiFallback(options) {
  5 + options = options || {};
  6 + var logger = getLogger(options);
  7 +
  8 + return function (req, res, next) {
  9 + var headers = req.headers;
  10 + if (req.method !== 'GET') {
  11 + logger(
  12 + 'Not rewriting',
  13 + req.method,
  14 + req.url,
  15 + 'because the method is not GET.'
  16 + );
  17 + return next();
  18 + } else if (!headers || typeof headers.accept !== 'string') {
  19 + logger(
  20 + 'Not rewriting',
  21 + req.method,
  22 + req.url,
  23 + 'because the client did not send an HTTP accept header.'
  24 + );
  25 + return next();
  26 + } else if (headers.accept.indexOf('application/json') === 0) {
  27 + logger(
  28 + 'Not rewriting',
  29 + req.method,
  30 + req.url,
  31 + 'because the client prefers JSON.'
  32 + );
  33 + return next();
  34 + } else if (!acceptsHtml(headers.accept, options)) {
  35 + logger(
  36 + 'Not rewriting',
  37 + req.method,
  38 + req.url,
  39 + 'because the client does not accept HTML.'
  40 + );
  41 + return next();
  42 + }
  43 +
  44 + var parsedUrl = url.parse(req.url);
  45 + var rewriteTarget;
  46 + options.rewrites = options.rewrites || [];
  47 +
  48 + for (var i = 0; i < options.rewrites.length; i++) {
  49 + var rewrite = options.rewrites[i];
  50 + var match = parsedUrl.pathname.match(rewrite.from);
  51 + if (match !== null) {
  52 + rewriteTarget = evaluateRewriteRule(parsedUrl, match, rewrite.to);
  53 + logger('Rewriting', req.method, req.url, 'to', rewriteTarget);
  54 + req.url = rewriteTarget;
  55 + return next();
  56 + }
  57 + }
  58 +
  59 + if (parsedUrl.pathname.indexOf('.') !== -1 &&
  60 + options.disableDotRule !== true) {
  61 + logger(
  62 + 'Not rewriting',
  63 + req.method,
  64 + req.url,
  65 + 'because the path includes a dot (.) character.'
  66 + );
  67 + return next();
  68 + }
  69 +
  70 + if (options.disableIndex) {
  71 + return next();
  72 + }
  73 +
  74 + rewriteTarget = options.index || '/index.html';
  75 + logger('Rewriting', req.method, req.url, 'to', rewriteTarget);
  76 + req.url = rewriteTarget;
  77 + next();
  78 + };
  79 +};
  80 +
  81 +function evaluateRewriteRule(parsedUrl, match, rule) {
  82 + if (typeof rule === 'string') {
  83 + return rule;
  84 + } else if (typeof rule !== 'function') {
  85 + throw new Error('Rewrite rule can only be of type string of function.');
  86 + }
  87 +
  88 + return rule({
  89 + parsedUrl: parsedUrl,
  90 + match: match
  91 + });
  92 +}
  93 +
  94 +function acceptsHtml(header, options) {
  95 + options.htmlAcceptHeaders = options.htmlAcceptHeaders || ['text/html', '*/*'];
  96 + for (var i = 0; i < options.htmlAcceptHeaders.length; i++) {
  97 + if (header.indexOf(options.htmlAcceptHeaders[i]) !== -1) {
  98 + return true;
  99 + }
  100 + }
  101 + return false;
  102 +}
  103 +
  104 +function getLogger(options) {
  105 + if (options && options.logger) {
  106 + return options.logger;
  107 + } else if (options && options.verbose) {
  108 + return console.log.bind(console);
  109 + }
  110 + return function () { };
  111 +}