window.open() 在 AJAX 成功上的工作方式不同

Posted

技术标签:

【中文标题】window.open() 在 AJAX 成功上的工作方式不同【英文标题】:window.open() works different on AJAX success 【发布时间】:2012-04-30 16:34:47 【问题描述】:

如果我只是给你看这个例子,我会更容易解释这个问题 -> http://jsfiddle.net/RU2SM/ 如您所见,有 2 个按钮,一个称为“AJAX”,一个称为“Direct”...因此,如果您单击“Direct”,它将打开窗口(Chrome 上的新标签),但如果我尝试制作 window.open( ) 在 AJAX 成功处理程序上,它的工作方式不同。 我确定问题来自 AJAX,但我不知道如何解决它。 将欣赏任何好主意。 谢谢

【问题讨论】:

window.open(url) different behavior - same code, different timing 和 extjs 4.0 inconsistent window.open() behavior when called within Ext.Ajax.request() 的可能重复 【参考方案1】:

在 ajax 调用成功后实现任何逻辑的更好方法是,每次 ajax 调用执行时都会触发一个事件,即 $.ajax.Request.done$.ajax.Request.fail $.ajax.Request.done(function() if(success) // 实现逻辑 );

【讨论】:

【参考方案2】:

另外值得一提的是,使用 async: false 然后调用 window.open 可以在 chrome 和 firefox 中工作,但会在 safari 中造成麻烦……它甚至没有提供弹出窗口被阻止的信息

【讨论】:

【参考方案3】:

这就像一个魅力:

// Direct window.open()
$('#btnDirect').on('click',function()
    window.open('http://google.com')
)
var success = false;  //NOTE THIS

// AJAX window.open()
$('#btnAJAX').on("click", function()
    $.ajax(
      url: "/user/login/",
      context: document.body,
      async:false,   //NOTE THIS
      success: function()  //THIS ALSO CHANGED
         success = true
      
    );
    if(success) //AND THIS CHANGED
      window.open('http://google.com')
    
)

它的作用是当 Ajax 调用成功时,它会将变量 success 设置为 true。async:false 属性确保在 Ajax 调用完成后触发 if 语句。 因此 window.open 在与您的直接链接相同的情况下被触发。

【讨论】:

非异步请求存在一些陷阱,如果您请求的页面可能有任何延迟,则不应使用它们。来自jQuery documentation:“请注意,同步请求可能会暂时锁定浏览器,从而在请求处于活动状态时禁用任何操作。” 没错,使用此解决方案时必须小心,但这是在相同情况下执行这两个功能的唯一方法(据我所知)。因为即使您允许使用 Ajax 版本的弹出窗口,它也会创建一个弹出窗口,它不会像直接调用那样打开另一个选项卡。我不确切知道为什么行为会有所不同,但这似乎可以解决问题。 谢谢,正如你所说,它“像魅力一样工作”:) 为了防止浏览器长时间冻结,我添加了 timeout=2000... 请记住,如果您添加 timeout=2000,并且由于某种原因 Ajax 调用时间超过 2 秒,则窗口将永远不会打开。也许是重置计时器的 else 语句?或您的 Ajax 调用中的失败属性,这会使计时器不重置。 仅供参考,这不再适用于 Chrome 版本 30 或 IE 10.0.4【参考方案4】:

问题是浏览器通常会阻止window.opens,除非它们被调用以直接响应用户操作。这就是为什么您的点击处理程序有效(点击是用户操作)但您的 AJAX 处理程序无效的原因。

一种解决方案是在初始单击操作期间打开窗口,然后在 AJAX 成功时更新其位置(或在 AJAX 失败时再次关闭)。

否则,您必须让用户在其浏览器中明确允许来自您的域的弹出窗口。

【讨论】:

是的,这也是解决方案,但只有在响应中有一些特定信息时我才需要打开一个窗口......所以这对我来说不是一个好的解决方案,但可能会对某人有所帮助其他 (1+)

以上是关于window.open() 在 AJAX 成功上的工作方式不同的主要内容,如果未能解决你的问题,请参考以下文章

ajax请求成功后新窗口window.open()被拦截的解决方法

ajax回调中window.open弹窗被Chrome81拦截的解决方法

js延迟window.open window.location几秒之后跳转

angularjs 中打开新的浏览器窗口(解决window.open(),浏览器拦截问题)

ajax请求window.open()被拦截

window.open方法被浏览器拦截的处理方式