关于即将弃用 JavaScript 对话框的选择词

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 $200 免费信用额度!

它可能是很多人在 JavaScript 中学习的第一件事

alert("Hello, World");

有一天,在 CodePen,我们醒来后发现大量客户支持票证表明他们的 Pens 坏了,这最终归结为 Chrome 的一个版本,在该版本中,他们从跨域 iframe 中删除了 alert() 的功能。 以及所有其他原生“JavaScript 对话框”,如 confirm()prompt() 以及我不知道的别的什么(onbeforeunload?、.htpasswd 保护的资产?)。

跨域 iframe 本质上是 CodePen 工作方式的核心。 您编写代码,我们在一个与 CodePen 本身没有相同域的 iframe 中为您执行代码,作为最基本的安全性防御。 我们没有听到任何预警或任何消息,但我相信 计划已经公布

我在 Twitter 上发推 表达了我的沮丧。 我理解这里存在潜在的安全问题。 JavaScript 对话框无论是由 iframe 触发还是非 iframe 触发,看起来都一样,因此,当它们是由 iframe 触发时,尤其是在父页面可能几乎无法控制的跨域 iframe 中,它们会让人感到困惑。 当然,除了像 CodePen 这样的网站。 Chrome 也提到了性能问题,因为这些 JavaScript 对话框的本质是当打开时会阻塞主线程,这实际上会停止所有操作。

iframe 可能存在各种安全和 UX 烦人问题。 这就是沙箱存在的意义。 我可以这样做

<iframe sandbox></iframe>

那个东西被锁定了。 如果某些表单试图在那里提交某些东西:不行,不起作用。 如果它试图触发下载怎么办? 不行。 要求设备访问? 不可能。 它甚至无法加载任何 JavaScript 除非我允许它

<iframe sandbox="allow-scripts allow-downloads ...etc"></iframe>

那么为什么不为 JavaScript 对话框添加一个属性呢? 具有讽刺意味的是,已经有一个属性:allow-modals。 我不太确定为什么这还不够好,但据我了解,在跨域 iframe 中删除 JavaScript 对话框只是一个过渡步骤,最终目标是:将它们从 Web 平台中彻底删除。

天哪。 彻底? 就是这个词。 想象一下有多少编程教程会因此彻底失效。

目前,即使是跨域删除也要推迟到 2022 年 1 月,但据我们所知,这将继续进行,然后将采取后续步骤将它们彻底删除。 这是由 Chrome 主导的,但 状态报告 表明 Firefox 和 Safari 都支持这项更改。 此外,这是 一个规范更改,所以我想我们可以对所有地方都指手画脚,如果你像我一样,觉得这件事处理得不好。

到目前为止,我们被告知的解决方案是使用 postMessage,如果你真的绝对需要保留跨域 iframe 的此功能。 这会将用户在 window.alert 中使用的字符串发送到父页面,并从那里触发警报。 我不是这里的最大粉丝,因为

  1. postMessage 不会像 JavaScript 对话框那样阻塞。 这会改变应用程序流程。
  2. 我必须将代码注入到用户的代码中。 这是新的技术债务,它会损害预期用户输出的期望(例如,在他们的 HTML 中添加一个额外的 <script> 会带来奇怪的影响,例如改变 :nth-child 和朋友的选择方式)。
  3. 我一般担心将任何用户生成的內容传递给父页面执行。 我相信有一些理论上的方法可以安全地执行此操作,但 XSS 攻击媒介总是出人意料地巧妙。

即使是更低调的建议,比如 window.alert = console.log,也存在本质上相同的问题。

请允许我将话筒交给其他人,让他们发表自己的意见。

警报不能被包含在 iframe 中,而不是显示在父窗口中吗?

Jaden BaptistaTwitter

是的,拜托! 这难道不会解决很大一部分问题吗? 同时使这些对话框的 UX 更有用? 将这些对话框放在 <iframe>内部

从“不要破坏网络”到“不要破坏 90% 的网络”,再到“不要破坏我们同意的网络内容”。

Matthew PhillipsTwitter

我尊重人们想要摆脱 [HTML 规范中] 不优雅的部分的愿望,这些部分可以被视为历史错误,会导致实现复杂性,但我无法摆脱一种感觉,那就是现有的用例没有得到足够的尊重或好奇心。

Dan AbramovTwitter

我觉得很奇怪,这是 HTML 规范的一部分,而不是 JavaScript 规范。 是不是?

我一直认为有一种“首要指令”,就是不要破坏网络? 我见过一些基于网络的游戏,它们使用 alert 作为“暂停”,利用其阻塞特性作为一种功能。 例如:<button onclick="alert('paused')">暂停</button>[。] 有趣,但事实如此。

Ben LeshTwitter

有人引用了一个指标,即只有 0.006% 的页面浏览量包含使用这些函数的跨域 iframe,但是

对于像 confirm() 这样的东西来说,这似乎是一个误导性的指标。 例如,如果帐户删除流程使用 confirm() 并且由于对它的更改而中断,这并不意味着帐户删除流程不重要。 这只意味着人们不会在每次会话中都点击它。

Dan AbramovTwitter

让我最担心的是:alert() 是一回事,但 confirm() 实际上会返回 truefalse,这意味着它在程序中是一种逻辑控制结构。 删除它会毫无疑问地破坏网站。 Chris Ferdinandi 向我展示了一个使用它的不起眼的小网站

说到 Chris

居高临下的“你真的读过吗,这很清楚”的反复说辞非常傲慢。 这相当于开发人员文档中的“仅仅”或“简单”。

我读过它。 我没有理解。 这就是为什么我会询问一个专门从事向开发人员传达 Chrome 对平台更改的人。

这并不仅仅限于 Chrome 的一位开发人员。 整个讨论此更改的线程都充满了恳求 Chrome 不要推进此提案的人,因为这会导致所有事情都失效。

Chris Ferdinandi“Google vs. 网络”

这是 Jeremy 的观点

[…] 在网络上,不会经常出现重大更改。 它们是——而且应该——很少出现的。 如果这种情况发生变化,网络在 可预测性 方面将受到严重影响。

其次,不是 web 开发人员有责任跟踪可能被弃用的旧功能。 这是浏览器制造商的责任。 我真诚地希望我们不会被要求咨询一个名为 canistilluse.com 的网站。

Jeremy Keith,“基础”

我已经描绘了一幅相当黯淡的画面。 说实话,有一些推文带有“太好了!!终于!!” 的感觉,但在我看来,它们更多地是随机的 Google 吹捧,而不是批判性的评估。

信不信由你,我通常是 Google 的粉丝,我认为他们在推动网络向前发展方面做得很好。 我也认为,当看到问题时,指手画脚并要求他们做得更好是合适的。 这里的“更好”意味着更多开发者和用户参与,以阐明情况,更多关于潜在影响和过渡想法的讨论,以及更多对改变未来方向的开放态度。