更新时间:
放弃使用
jsdom
如前所述,因为它在呈现的页面上执行脚本,而这不是预期的。可能可以使用
runScripts
选项,仍将受到性能影响。渲染字符串上的Regex替换更快、更安全。下面的示例更新以反映它。
今天我遇到了同样的问题。启用了角度应用和通用支撑,以及
@angular/flex-layout
。
在浏览器上呈现此应用程序时,
ObservableMedia
属于
@角度/弯曲布局
正确报告媒体,例如:
{
matches: true,
mediaQuery: "(min-width: 1280px) and (max-width: 1919px)",
mqAlias: "lg",
property: "",
suffix: "Lg"
}
在服务器上呈现相同的应用程序时:
{
matches: true,
mediaQuery: "all",
mqAlias: "",
property: "",
suffix: ""
}
所以基本上,服务器端在默认情况下不知道客户端的媒体参数,这是可以理解的。
如果您有某种传递客户端设备宽度的机制(例如通过cookie、个性化API等),那么您可以使用
jsdom
正则表达式字符串替换
修改呈现的文档。大致如下所示:
function updateMetaViewport(html: string, deviceWidth?: number, deviceHeight?: number): string {
const width = `width=${deviceWidth ? deviceWidth : 'device-width'}`;
const height = deviceHeight ? `, height=${deviceHeight}` : '';
const content = `${width}${height}, initial-scale=1`;
const replaced = html.replace(
/<head>((?:.|\n|\r)+?)<meta name="viewport" content="(.*)">((?:.|\n|\r)+?)<\/head>/i,
`<head>$1<meta name="viewport" content="${content}">$3</head>`
);
return replaced;
}
router.get('*', (req, res) => {
const userDeviceWidth = req.userDeviceWidth;
const userDeviceHeight = req.userDeviceHeight;
const document = updateMetaViewport(indexHtmlDocument, userDeviceWidth, userDeviceHeight);
res.render('index.html', {
bootstrap: AppServerModuleNgFactory,
providers: [provideModuleMap(LAZY_MODULE_MAP)],
url: req.url,
document,
req,
res
}, (err, html) => {
if (err) {
res.status(500).send(`Internal Server Error: ${err.name}: ${err.message}`);
} else {
const relaxViewportDocument = updateMetaViewport(html);
res.status(200).send(relaxViewportDocument);
}
});
});
然后服务器端渲染
@角度/弯曲布局
将根据:
{
matches: true,
mediaQuery: '(min-width: 600px) and (max-width: 959px)',
mqAlias: 'sm',
suffix: 'Sm',
property: ''
}
这是正确且更有利的,因为响应组件的样式和布局将完全符合客户的期望。