nodejs&react:根据请求渲染另一个HTML文件

时间:2019-05-19 11:14:40

标签: javascript node.js reactjs ssr

我正在尝试在我们的项目中实现amp页面。

到目前为止,我已经提出了以下解决方案:如果url中有一个查询,例如:myurl.com?amp=1,则页面将在必要的标记下完全重绘。问题是,目前,我们的服务器已配置为可以在2个html文件中进行选择,如果出错,则带有错误的标记,如果没有,则返回常规索引。它是这样的:

yield this.render('index', {
        state: encodeURIComponent(JSON.stringify(state)),
        body: renderToString(
            <Provider store={store}>
                <RouterContext {...props}/>
            </Provider>
        )
    });

和错误

app.use(isProduction ? function * error(next) { // error handler
    try {
        yield next;
        if (this.response.status === 404 && !this.response.body) {
            this.throw(404);
        }
    } catch (err) {
        const STATUS_CODES = require('http').STATUS_CODES;
        const seo = require('app/modules/seo').initialState;

        this.status = err.status = err.status || 500;
        if (err instanceof URIError) {
            this.redirect('/search');
            return;
        }
        err.message = STATUS_CODES[this.status];
        this.app.emit('error', err, this);

        yield this.render('error', {
            assets,
            err,
            seo: {...seo, long_title: `${err.status} – ${seo.long_title}`}
        });
    }
} : error());
componentDidMount() {
        if (this.state.isAmp) {
            document.write(expotedAmpMarkup(this.props.body))
        };
}

请告诉我,在URL上有请求时,如何在服务器端禁用标准标记?

是否可以在服务器端进行新页面的绘制?

对于造成混淆的文字,我深表歉意。我知道的很少,无法提出一个有力的问题,除了这个论坛,我没有人要寻求帮助。

如有必要,可以发送整个服务器和Webpack配置。 准备回答任何问题。谢谢。

1 个答案:

答案 0 :(得分:1)

您可以根据需要在SSR上呈现所需的任何页面。

您可以看一下我处理路线的SSR应用程序: https://github.com/tornado1979/ssr-rentalcars

一些关键点如下:

客户端“ index.js”:

.....
import { BrowserRouter } from 'react-router-dom'
import { renderRoutes } from 'react-router-config'

import store from './store'
import Routes from './components/Router/routes'


ReactDOM.hydrate(
<Provider store={store}>
  <BrowserRouter>
    <div>{renderRoutes(Routes)}</div>
  </BrowserRouter>
</Provider>,
document.getElementById('root'),
)

客户端“ routes.js”,在这里您放置了所有页面

export default [
{
  ...App,
  routes: [
   {
     ...HomePage,
     description: "Compare car hire deals and find the cheapest prices in.",
    keywords: 'car hire, cheap car hire, car rental uk,  rent a car, car rentals, uk car car, cheap car rentals spain, cheap car rental usa, carrentals, rent car, car hire comparison, carrental, carhire, compare car hire, car rental comparison, rentalcars, rental cars',
    path: '/home',
    title: '.......',
  },
  {
    ...About,
    description: 'About Compare car hire deals...',
    keywords: 'car hire, ...',
    path: '/about',
    title: 'About - Rentalcars',
  },
  {
    ...NotFoundPage,
    description: '',
    keywords: '',
    title: 'page not found - Rentalcars',
  },
],
 },
  ]

服务器端,“ index.js” 您收到请求并将正确的组件发送给客户端      //您需要此路由器:
       import { matchRoutes } from 'react-router-config'

app.get('*', (req, res) => {
  const store = createStore()
   // Initialize and load data into the store
   const promises = matchRoutes(Routes, req.path).map(({ route }) => {
    return route.loadData ? route.loadData(store) : null
  })

Promise.all(promises).then(() => {
  const context = {}
  const content = renderer(req, store, context)

  if (context.notFound) {
    res.status(404)
  }

  return res.send(content)
 }).catch(error => res.status(500).send(`Internal Server Error:, 
${error}`))
})

渲染pagestore并将其传递给客户端'render.js'

export default (req, store, context = {}) => {
const content = renderToString(
<Provider store={store}>
  <StaticRouter context={context} location={req.path}>
    <div>{renderRoutes(Routes)}</div>
  </StaticRouter>
</Provider>,

)      const helmet = Helmet.renderStatic()

返回(     <!DOCTYPE html> <html ${helmet.htmlAttributes.toString()}> <head> <meta charset="UTF-8"> ${helmet.title.toString()} ${helmet.meta.toString()} </head> <body ${helmet.bodyAttributes.toString()}> <div id="root">${content}</div> <script> window.INITIAL_STATE = ${serialize(store.getState())} </script> <script src="bundle.js"></script> </body> </html>   ) }

希望对您有帮助。