Маршрутизация на NodeJS для рендеринга на стороне сервера - PullRequest
2 голосов
/ 13 мая 2019

Я настраиваю сервер nodejs, способный выполнять серверный рендеринг для приложенияactjs В настоящее время я борюсь с определенными типами маршрутов. то есть маршруты с более длинными путями.

Я пытался настроить сервер 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 возвращает HTML-файл, но называет его последним фрагментом пути в маршруте.

Например, 2) он назовет его 123.html и выдаст ошибку синтаксического анализа на стороне клиента в браузере. (см. скриншот)

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

Здесь вы можете увидеть ответ и другие скриншоты, чтобы уточнить

HTML-клиент получает Html file client receives

Ошибка клиента Clientside Error

Заголовки Response Type

...