17

我目前正在阅读一本关于 React 和 Universal 应用程序的书,其中作者声称以下是将初始状态从服务器传递到客户端的最佳实践:

服务器.js

import React from 'react';
import {renderToStaticMarkup} from 'react-dom/server';
import Myapp from '../MyApp';
import api from '../services';

function renderPage(html, initialData) {
    return `
        <html>
            <body>
                ${html}
            </body>
            <script>
                window.__INITIAL_STATE__ = ${JSON.stringify(initialData)};
            </script>
            <script src="bundle.js"></script>
        </html>
    `;
}

export default function(request, reply) {
    const initialData = api.getData();
    const html = renderToStaticMarkup(<MyApp />);
    reply(renderPage(html, initialData);
}

然后,在客户端中,您将读取如下数据:

捆绑.js

const initialData = window.__INITIAL_STATE__ || {};
const mountNode = document.getElementById('root');
ReactDOM.render(<MyApp />, mountNode);

据我了解,初始状态首先转换为字符串,然后作为全局对象文字附加到窗口对象。

这个解决方案对我来说看起来很粗糙。这本书于 2016 年年中发布。使用方法window.__INITIAL_STATE__仍然是如何做到这一点还是有更好的解决方案?

例如,我可以想象可以在单独的微服务调用中提供初始状态,然后也可以比将数据直接嵌入到文档中更好地缓存,因为这样初始状态数据必须在每个页面刷新的时间,即使数据没有改变。

4

2 回答 2

16

简单的回答:是的。

但我不确定为什么没有人指出你有一个非常常见的 XSS 漏洞JSON.stringify(initialData),而你想要做的是:

import serialize from 'serialize-javascript';

 window.__INITIAL_STATE__ = ${serialize(initialData)};
于 2018-01-08T02:53:59.520 回答
0

HTTP通过缓存响应来工作,在您的情况下,如果初始状态始终相同,您也可以将其缓存在服务器端并将其显示在页面中,它会更快地工作,因为反应将立即访问此值所以它不必等待。此外,您还可以强制浏览器缓存页面,因此页面的响应将与初始状态不变的情况相同。

对于额外的调用请求,您依赖浏览器来缓存该调用,但您必须构建一个额外的步骤,在信息到达时重新渲染或阻止响应渲染,直到信息准备好。

所以我会选择数字 1,它给你更多的灵活性和其他一些不错的东西,比如服务器渲染,这可以在服务器中加载状态后轻松实现。

于 2017-05-03T09:22:13.233 回答