【发布时间】:2020-12-16 10:05:12
【问题描述】:
我们有一个结合了无头 CMS 的 NextJS 页面。
在这个 CMS 中,我为管理员添加了一个选项,可以保存任意的 sn-ps 以注入到头部或主体的末端。
在 nextJS 中,我尝试以两种方式实现它:
- 我在一个带有“dangerouslySetInnerHTML”的 div 中注入了 HTML:
{this.bodyScripts && (
<div dangerouslySetInnerHTML={{__html: `${this.bodyScripts}`}} />
)}
这行得通。但是,我有两个问题。 sn-p 并不是真正在结束 body 标记之前的末尾,它被包裹在一个不必要的 div 中。这两个问题都是偏好而不是真正的问题。 这个方法不能在页头中使用,因为我没有可以用来包装它的 HTML 标记。
- 我尝试在我的页面组件的
componentDidMount函数中注入sn-ps:
public componentDidMount() {
if (this.headerScripts) {
const head = document.getElementsByTagName('head')[0];
head.insertAdjacentHTML('beforeend', `${headerScripts}`);
}
if (this.bodyScripts) {
const body = document.getElementsByTagName('body')[0];
body.insertAdjacentHTML('beforeend',`${this.bodyScripts}`);
}
}
sn-ps 被注入,看起来它们不是 HTML 编码或任何东西。但他们不会被处决。
作为参考,我尝试创建一个脚本元素并将其注入:
const body = document.getElementsByTagName('body')[0];
let myScript = document.createElement("script");
myScript.src = 'some URL to a script';
body.appendChild(myScript);
这行得通。但这违背了注入任意脚本的目的,管理员应该可以选择添加他想要的任何内容。我知道安全风险,但我们还是决定这样做:)
我也尝试过使用 appendChild:
const body = document.getElementsByTagName('body')[0];
let div = document.createElement("div");
div.innerHTML = `${this.bodyScripts}`;
body.appendChild(div);
这也不起作用。我完全感到困惑,因为我不明白为什么创建脚本标签并注入它会起作用,但注入字符串变量却不会。我使用普通的 javascript 来做到这一点,据我所知,没有任何东西被净化......
任何帮助将不胜感激:)
【问题讨论】:
-
你可能想看看这个模块github.com/nfl/react-helmet
标签: javascript reactjs typescript next.js