我的 ember 应用程序必须打开一个窗口(通过外部 JS API)并且相应的 API 指令应该由 Controller 操作调用,因为它应该然后转换到另一个路由。
我的问题是当操作被触发时,窗口不会打开。它只会从直接处理 trusted event 的代码中打开,即来自用户的点击。
因此,远离 Ember 并使用 jQuery 进行调试,并假设 window.open()
指令位于 MyLib.login()
中,此代码 一个作品:
$('#mybutton').click(() ->
MyLib.login()
)
但是这段代码B不会:
$.myNamespace = {
myLoginFunction: () ->
MyLib.login()
}
$('#mybutton').click(() ->
$.myNamespace.myLoginFunction()
)
并且 ember action 也不会工作,生成与 B 相同的代码,经过调试后,window.open()
将返回一个 undefined object .
我的问题是:
- 有没有办法让代码 B 工作? (出于因式分解的原因,这很有意义)
- 有没有办法让 Ember 操作也能起作用?
PS:为了更加透明,我所说的库是 Deezer 的 JavaScript SDK。
PPS:请原谅我的 CoffeeScript
最佳答案
首先,您在这里要对抗的是目前大多数浏览器默认启用的弹出窗口拦截器。
我只熟悉弹出窗口阻止程序在 Firefox 中的工作方式(最初在 bug 252326 中实现,此后没有太大变化),但其他浏览器类似。这个想法很简单:弹出窗口只能在响应明确的用户操作时打开。这超出了受信任的事件范围,只有鼠标点击和按键才算作此类操作。所有其他弹出窗口都被认为是不受欢迎的,将被阻止。
所以,回答你的问题:
How can I make an Ember action considered a trusted event so that window.open succeeds?
任何响应用户操作而运行的代码(意味着同步代码执行)都可以打开弹出窗口。至于其他代码,例如延迟操作(包括对响应用户操作而执行的同步代码的异步回调)或响应应用程序生成的事件的代码 - 弹出窗口阻止程序不会让其通过,您对此无能为力。 Web 应用程序不能伪造受信任的事件,就像它不能随意绕过弹出窗口阻止程序一样(任何一个都会成为安全问题)。
Is there a way an Ember action can also work?
您基本上有两个选择:
-
如果被阻止,
window.open()
将在 Firefox 中返回null
(在其他浏览器中的行为可能不同)。您可以检测到这一点并要求用户将您的站点添加到弹出窗口阻止程序异常(exception)。但是,他们中的大多数人会忽略此类请求。- 您改变了网络应用程序的工作方式。例如。您可以在用户单击“登录”按钮时打开一个空的弹出窗口,但稍后才用真实内容填充它。或者您可以将登录操作移动到弹出窗口中。或者您可以完全停止使用弹出窗口,而是在主窗口中显示一个图层。您的选择。
显然,第二种选择更有意义,所有网站都这样做。与浏览器的安全机制作斗争并不好玩。
关于javascript - 我怎样才能使 Ember 操作被视为受信任的事件,以便 window.open 成功?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26807489/