危险地反应SetInnerHTML用&字符破坏JSON配置

问题描述

我试图将amp-analytics脚本放入从Next.js生成的amp页面中,但是由于&字符,SetInnerHTML危险地破坏了JSON配置。

代码如下:

<amp-analytics id='analytics1' type='googleanalytics'>
  <script type='application/json' dangerouslySetInnerHTML={{ __html: `
    {
      "vars": {
        "account": "XX-XXXXXXXX-X"
      },"requests": {
         "experiment": "\${pageview}&xid=\${xid}&xvar=\${xvar}"
      }
    }
  ` }} />
</amp-analytics>

结果如下:

enter image description here

您会看到&字符已转换为\ u0026,现在amp-analytics标签不起作用。

我也尝试过:

<amp-analytics id='analytics1' type='googleanalytics'>
  <script type='application/json' dangerouslySetInnerHTML={{ __html: `
    {
      "vars": {
        "account": "XX-XXXXXXXX-X"
      },"requests": {
         "experiment": "${JSON.stringify('${pageview}&xid=${xid}&xvar=${xvar}')}"
      }
    }
  ` }} />
</amp-analytics>

但是没有有效的JSON(带有右和符号)

enter image description here

关于如何解决此问题的任何想法?

事实证明,发生这种情况的原因是Next.js中的AMP Optimizer — github.com/ampproject/amp-toolBox/pull/649现在,我必须找到这种情况的解决方

解决方法

您无需使用dangerouslySetInnerHTML,因为您只需要设置文本内容即可。仅在需要将HTML解析为DOM节点时才需要dangerouslySetInnerHTML

您可以这样设置文本内容:

<script type='application/json'>
  {JSON.stringify(
    {
      vars: {
        account: 'XX-XXXXXXXX-X',},requests: {
        experiment: `${pageview}&xid=${xid}&xvar=${xvar}`,}
  )}
</script>

如果您采用这种方式,React足够聪明,可以知道script标记中不需要HTML实体,因此这些&不会被转义(除非它是一个普通的HTML元素,例如div)。

您可以像这样(demo)进行验证:

const InnerHtmlLogger = ({ TagName }) => {
  const ref = useRef(null);

  useEffect(() => {
    console.log(TagName,ref.current.innerHTML);
  },[TagName]);

  return (
    <TagName ref={ref}>
      {JSON.stringify({
        '&': '&&','&&&': ['&&&&','&&&&&']
      })}
    </TagName>
  );
};

const App = () => {
  return (
    <>
      <InnerHtmlLogger TagName='div' />
      <InnerHtmlLogger TagName='script' />
    </>
  );
}

// Log output:
// div {"&amp;":"&amp;&amp;","&amp;&amp;&amp;":["&amp;&amp;&amp;&amp;","&amp;&amp;&amp;&amp;&amp;"]}
// script {"&":"&&","&&&":["&&&&","&&&&&"]}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...