我正在设置一个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
在这里您可以查看响应和其他屏幕截图以进行澄清