反应 16.9.0“javascript:;” href替代品? [复制]
Posted
技术标签:
【中文标题】反应 16.9.0“javascript:;” href替代品? [复制]【英文标题】:React 16.9.0 "javascript:;" href alternative? [duplicate] 【发布时间】:2019-12-22 03:24:54 【问题描述】:更新到 React 16.9.0 后,我收到了如下严重警告:
警告:未来版本的 React 将阻止 javascript: URL 作为安全预防措施。如果可以,请改用事件处理程序。如果您需要生成不安全的 html,请尝试使用 dangerouslySetInnerHTML。 React 通过了“javascript:;”。
它来自这样的代码:
const Component = (someAction) => (
<a href="javascript:void(0)" onClick=someAction>click me</a>
);
查看关于 HTML 中 which “href” value should I use for JavaScript links 的 *** 问题,你们中的大多数人似乎都同意 javascript:void(0)
是最好的选择,这在 React 16.9.0 中将不再可能。
仅用href="#"
替换是有问题的,因为浏览器会滚动到页面顶部并更改显示的 URL。特别是如果您使用哈希链接进行路由,这是非常有问题的。
我可以更新我的整个代码库以在每个事件处理程序中添加e.preventDefault();
,但这似乎很难做到,尤其是当事件处理程序是从 Redux 操作创建者或挂钩自动创建时。我不会到处寻找“只包括e.preventDefault();
”的答案!
还使用<button>
意味着我必须处理许多不需要的样式。
所以我想知道:是否有任何特定于库 React 的解决方案来获得一个有效的 <a>
链接,它只会触发一个没有副作用的操作?我想尽可能少地更改代码并摆脱弃用警告。
【问题讨论】:
@EmileBergeron 但我想避免一直手动调用e.preventDefault()
。
如果你有那么多的按钮链接,我会选择按钮的方式。您甚至可以使用div
,尽管这需要一些可访问性调整。
如果它是一个永远不会用作链接的链接,它应该是一个按钮。
是的,不要使用锚点作为按钮。对于语义标记和可访问性来说,这是一种不好的做法。
已经有人质疑 react 团队添加这个警告的决定了:github.com/facebook/react/pull/15047#issuecomment-521736797
【参考方案1】:
在反应blog post:
以
javascript:
开头的网址是危险的攻击面 因为很容易在标签中意外包含未经处理的输出 喜欢<a href>
并创建一个安全漏洞。在 React 16.9 中,这种模式继续有效,但它会记录一个 警告。如果你使用
javascript:
URLs 进行逻辑,请尝试使用 React 事件 处理程序。
我个人更喜欢这样使用它:
<a href="#!" onClick=clickAction>Link</a>
【讨论】:
我已阅读博文。这仍然给我留下了以某种方式调用e.preventDefault()
的问题。【参考方案2】:
我想出了一个这样的组件:
import React, useCallback from 'react';
function AHrefJavascript( children, onClick, ...props )
const handleClick = useCallback(
e =>
e.preventDefault();
return onClick(e);
,
[onClick]
);
return (
<a href="#javascript" ...props onClick=handleClick>
children
</a>
);
它只会包装事件处理程序以创建一个新的也调用e.preventDefault()
的事件处理程序。它将向href
添加一个哈希链接,这不会触发弃用警告。当传入的处理程序更新时,使用钩子的功能它只会更改事件处理程序。一个问题是在浏览器中您仍然可以在新选项卡中打开此链接,因此它不如带有javascript:void(0)
的链接好,这会阻止这种情况。
使用方便,组件如下:
const Component = (someAction) => (
<AHrefJavascript onClick=someAction>click me</a>
);
因此,可能有人可以在整个项目中将a href="javascript:void(0)"
替换为AHrefJavascript
,然后在各处添加组件的导入。
最后,也许最好的选择是使用 <button>
并通过箍来删除所有不需要的样式。
【讨论】:
只调用e.preventDefault()
的组件似乎有点过头了,有时,您还想保留默认行为。虽然使用某种Link
组件来管理不同的行为是个好主意,比如跟踪、路由、样式等。以上是关于反应 16.9.0“javascript:;” href替代品? [复制]的主要内容,如果未能解决你的问题,请参考以下文章