繁体   English   中英

用 JS function 替换 href 链接

[英]Replace href link with a JS function

在我的反应 electron 应用程序中,它正在使用 API,我收到 JSON 值以将数据显示到组件中。 例如,我有一个Features组件:

const Features = () => {
  const { title } = useSelector(({ titles }) => titles);
  let string = title.features;
  // the string can contain some html tags. Example bellow:
  // sting = 'This is a string containing a href to <a href="www.google.com">Google</a>';

  string = string.replace(/href="(.*?)"/g, function() {
    return `onClick="${() => shell.openExternal('www.google.com')}"`;
  });

  return (
    <>
      <Heading>Features</Heading>
      <Text content={parsedHTML} />
    </>
  );
};

我想要的是用onClick替换href属性并分配电子的shell.openExternal() function。

string.replace()回调 function 会这样做,但是当我单击<a>元素时,应用程序会抛出下一个错误:

错误:uncaughtException:预期onClick侦听器是 function,而不是string类型的值。

更新

也试过这个逻辑,同样的错误发生:

  global.openInBrowser = openInBrowser; // openInBrowser is basically a function that calls shell.openExternal(url)

  const re = new RegExp('<a([^>]* )href="([^"]+)"', 'g');
  string = string.replace(re, '<a$1href="#" onClick="openInBrowser(\'$2\')"');

这是 沙盒代表的链接。

我该如何正确地做到这一点?

Not sure on specifics of electron, but passing a (function(){functionName()})() would not work in html if there is no functionName variable available on window scope. 在 electron 中有一个全球环境,这可能会回答您的问题:

const Features = () => {
  const { title } = useSelector(({ titles }) => titles);
  let string = title.features;
  // the string can contain some html tags. Example bellow:
  // sting = 'This is a string containing a href to <a href="www.google.com">Google</a>';
  
  function runOpen(href){
      shell.openExternal(href)
  }      

  global.runOpen = runOpen;

  string = string.replace(/href="(.*?)"/g, function() {
    return `onClick="runOpen(${'www.google.com'})"`;
  });

  return (
    <>
      <Heading>Features</Heading>
      <Text content={parsedHTML} />
    </>
  );
};

如果它没有,你可以使用类似onclick="console.log(this)"的东西来找出 scope 是什么 onclick 运行,并在那里进一步分配你的 runOpen 变量。

未在 React 元素上设置onclick实际上是预期的行为。

因为在评估onclick字符串时存在 XSS 安全风险。 推荐的解决方案是在html-react-parser中使用replace选项。

您也可以使用dangerouslySetInnerHTML的SetInnerHTML,这会带来安全风险。

沙盒演示

export default function App() {
  let string =
    'This is a string containing html link to <a href="www.google.com">Google</a>';

  const re = new RegExp('<a([^>]* )href="([^"]+)"', "g");
  let replaced = string.replace(re, "<a onclick=\"alert('$2')\"");

  return (
    <div className="App">
      <p dangerouslySetInnerHTML={{__html: replaced}}></p>
      <p>{parse(string, {
        replace: domNode => {
          if (domNode.name === 'a') {
            let href = domNode.attribs.href
            domNode.attribs.onClick = () => { alert(href) }
            delete domNode.attribs.href
          }
        }
      })}</p>
    </div>
  );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM