我有一个运行ExpressJS,Next和React的Node应用程序,该应用程序根据收到的标头动态加载不同的布局。该标头由Nginx在虚拟主机中设置。因此,想象一下必须加载同一应用程序的3个不同域,但是每个虚拟主机在此标头中都有一个不同的值,因此这是应用程序读取并返回正确布局的内容。
此方法将按预期工作,直到此标头中具有不同值的2个请求同时到达。发生这种情况时,其中一个的响应可能会完全或部分与另一个重叠。
我知道app.local和request.local的功能可以隔离请求/响应,但是玩了之后,它不能解决我的问题,或者我使用的方式错误。
在此链接上,您可以看到应用程序的软件架构概念(简化)。如果要重现该错误,则必须使用此标头设置2个具有不同值的虚拟主机,然后一次加载两个域:
https://codesandbox.io/s/zmoq4q3mp
任何帮助将不胜感激。
非常感谢您。
答案 0 :(得分:1)
问题很简单,您要将当前模板分配给BeforeEach
,这是整个应用程序共享的单例,它不是该请求唯一的。
因此,基本上,所有请求都在修改同一个config.layoutTpl
对象,这就是您遇到问题的原因。使用并发时,不能使用“全局变量”,否则会遇到此类问题。
您必须将数据从config
传递到_document.js
,或直接在_app.js
中获取模板,这是您当前唯一使用它的地方。
即使在下一步如何传递数据方面可能有更好的方法,也可以使用以下方法。
您需要做的而不是将模板分配给_document.js
,而是将其分配给config
,这对于每个请求都是唯一的。
_app.js
ctx
_document.js
export default withRedux(initStore)(
class MyApp extends App {
static async getInitialProps({ Component, ctx }) {
let layoutTpl = null;
if (ctx.req && !process.browser) {
const { layouttpl } = ctx.req.headers;
layoutTpl = layouttpl;
}
// Assign the current template, to the context
// This is unique for this specific request
ctx.layoutTpl = layoutTpl || config.layoutTpl;
return {
pageProps: Component.getInitialProps
? await Component.getInitialProps(ctx)
: {}
};
}
/* ... */
}