在NodeJS上进行服务器端渲染的路由

时间:2019-05-13 09:50:50

标签: javascript node.js reactjs serverside-rendering ssr

我正在设置一个nodejs服务器,该服务器能够为reactjs应用程序进行服务器端渲染。 目前,我正在努力应对某些类型的路线。即具有更长路径名的路由。

我尝试以不同方式设置nodejs服务器。更改了中间件的顺序。目前,我已从SSR流程中删除了所有路由,但仍无法正常工作。

// NodeJs Server.js
import '@babel/polyfill';
import express from 'express';
import bodyParser from 'body-parser';
import logger from 'morgan';
import cookieParser from 'cookie-parser';
import { ssrMiddleware, csrMiddleware } from './Middlewares';

const app = express();
const PORT = process.env.PORT || 3000;

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());

app.use(ssrMiddleware);
app.use(express.static('public'));
app.use(csrMiddleware);
app.use(express.static('public'));

app.listen(PORT, () => {
  console.log(`listening on ${PORT}`);
});
// CSR Middleware
import express from 'express';
import path from 'path';
import fs from 'fs';
import webConfig from '../../../webConfig';

const routerCSR = express.Router();

routerCSR.get(['*/:param', '*'], (req, res) => {
  // console.log(req, "csr request");
  const indexFile = path.resolve(webConfig.html.path, 'index.html');
  fs.readFile(indexFile, 'utf8', (err, data) => {
    if (err) {
      console.error('Something went wrong:', err);
      return res.status(500).send('Errorpage CSR 500er');
    }

    return res.status(200).send(data);
  });
});

export default routerCSR;
// SSR Middleware
import { SSRPaths } from 'Router/routes';
import { ssrRouter } from '../Router';

const ssrMiddleware = (req, res, next) => {
  const { path } = req;
  console.log('SSR', SSRPaths.includes(path), '\n with path: ', path);
  if (SSRPaths.includes(path)) return ssrRouter(req, res, next);
  return next();
};

export default ssrMiddleware;
// CSR Router
import express from 'express';
import path from 'path';
import fs from 'fs';
import webConfig from '../../../webConfig';

const routerCSR = express.Router();

routerCSR.get(['*/:param', '*'], (req, res) => {
  // console.log(req, "csr request");
  const indexFile = path.resolve(webConfig.html.path, 'index.html');
  fs.readFile(indexFile, 'utf8', (err, data) => {
    if (err) {
      console.error('Something went wrong:', err);
      return res.status(500).send('Errorpage CSR 500er');
    }

    return res.status(200).send(data);
  });
});

export default routerCSR;
// SSR Router
import express from 'express';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { StaticRouter } from 'react-router';
import { StoreManager } from 'Storage/redux';
import messages from 'Translations/languages';
import AppWrapper from 'AppWrapper';
import path from 'path';
import fs from 'fs';
import history from 'Router/history';
import App from '../../App';
import webConfig from '../../../webConfig';

const routerSSR = express.Router();

routerSSR.get(['*/:param', '*'], (req, res) => {
  const URL_Param = req.params.param || null; // eslint-disable-line
  const context = {
    URL_Param,
  };
  const routerConfig = { location: req.url, context, history };
  const content = ReactDOMServer.renderToString(
    <AppWrapper {... {
      StoreManager,
      Router: StaticRouter,
      routerConfig,
      messages,
      isSSR: true,
    }}
    >
      <App />
    </AppWrapper>,
  );
  const indexFile = path.resolve(webConfig.html.path, 'index.html');
  fs.readFile(indexFile, 'utf8', (err, data) => {
    if (err) {
      console.error('Something went wrong:', err);
      return res.status(500).send('Errorpage SSR 500er');
    }
    const preloadedState = StoreManager.store.getState();
    return res
      .status(200)
      .send(
        data
          .replace('<div id="root"></div>', `<div id="root">${content}</div>`)
          .replace('window.__PRELOADED_STATE__=false', `window.__PRELOADED_STATE__=${JSON.stringify(preloadedState).replace(
            /</g,
            '\\u003c',
          )}`),
      );
  });
});

export default routerSSR;
// SSRPaths
import Contact from 'Pages/Contact';
import DataPolicy from 'Pages/DataPolicy';
import Imprint from 'Pages/Imprint';
import Landing from 'Pages/Landing';
import SearchResult from 'Pages/SearchResult';


const Routes = {
  Contact: {
    exact: true,
    path: '/contact',
    component: Contact,
  },
  DataPolicy: {
    exact: true,
    path: '/data-policy',
    component: DataPolicy,
  },
  Imprint: {
    exact: true,
    path: '/imprint',
    component: Imprint,
  },
  Landing: {
    exact: true,
    path: '/',
    component: Landing,
  },
  LocationDetails: {
    exact: false,
    path: '/location/:id',
    component: LocationDetails,
  },
};

const ssrRoutesByName = [
  // 'Contact',
  // 'Imprint',
  // 'DataPolicy',
];

export const SSRRoutes = (() => {
  const res = {};
  ssrRoutesByName.forEach((name) => {
    res[name] = Routes[name];
  });
  return res;
})();

export const SSRPaths = (() => {
  const paths = [];
  Object.keys(SSRRoutes).map(key => SSRRoutes[key]).forEach((routeObj) => {
    if (routeObj.path) paths.push(routeObj.path);
  });
  return paths;
})();

export default Routes;

1)路径为1的路由工作正常,例如MyDomain.com/contact

2)路径为2或更大的路径不起作用,例如MyDomain.com/location/123

我希望服务器返回一个正常的index.html和客户端路由来处理该路由, 但是NodeJs Server确实返回了html文件,但将其命名为路由中路径名的最后一部分。

例如2),它将命名为123.html,并在浏览器的客户端抛出一些解析错误。 (请参见屏幕截图)

URL: http://localhost:3000/location/11

在这里您可以查看响应和其他屏幕截图以进行澄清

HTML文件客户端收到 Html file client receives

客户端错误 Clientside Error

标题 Response Type

0 个答案:

没有答案