在我的网站上有一个按钮,用于调用调用window.open
的函数,但是,最近需要在弹出窗口打开之前进行服务器端检查。
自从添加了执行AJAX调用的代码以来,浏览器会阻止弹出窗口,该弹出窗口是在AJAX调用的success
回调中打开的。我读过,如果没有用户点击事件调用,浏览器可能会阻止弹出窗口,所以我尝试将AJAX请求设置为async: false
,这解决了Firefox中的问题,但谷歌Chrome仍然阻止弹出窗口。有没有办法解决这个问题?
我可以将服务器端检查移动到弹出窗口中打开的页面,但是如果可能的话,我想在打开弹出窗口之前执行此操作。
代码:
<a id="attackButton" href="#">Attack Base!</a>
<script type="text/javascript">
$(function() {
$('#attackButton').click(function() {
$.ajax({
url: baseurl + '/index.php?option=com_pbbgs&format=raw&getinfo=goingame',
data: { 'gameid': 618 },
dataType: 'text',
async: false,
type: 'POST',
success: function(data) {
eval(data);
if (window.gameURL) {
goingameRaw();
}
}
});
return false;
});
});
function goingameRaw()
{
window.open(window.gameURL,'test','left=20,top=20,width=1024,height=640,toolbar=0,resizable=0,location=0');
}
</script>
示例响应正文:
window.gameURL="http://mydomain.com/index.php?option=com_pbbgs&format=raw&startgame=618&width=1024&height=640";checktutorial('js','attack');
答案 0 :(得分:46)
是的,弹出窗口应该是用户操作的直接结果。在ajax回调中执行它们不会起作用。此外,使用async:false
是不好的 - 在FF中,已知会阻止整个浏览器。想一想其他方法来做检查:
答案 1 :(得分:20)
跟进Emil的优秀答案,“你可以点击弹出窗口,稍后在回调触发时操纵它”。我使用了这个实现。
$('#attackButton').click(function() {
此处的新代码
var win = window.open('');
window.oldOpen = window.open;
window.open = function(url) { // reassignment function
win.location = url;
window.open = oldOpen;
win.focus();
}
结束新代码
$.ajax({
url: baseurl + '/index.php',
data: { 'gameid': 618 },
type: 'POST',
success: function(data) {
window.open('some url'); // will call reassignment function above
}
});
return false;
});
答案 2 :(得分:5)
您可以在onclick事件下打开一个未被阻止的窗口,如果您在ajax调用中打开它,则会将其视为弹出窗口。但是我使用这种方法成功了一段时间才打开弹出窗口而不被阻止。
http://en.nisi.ro/blog/development/javascript/open-new-window-window-open-seen-chrome-popup/
答案 3 :(得分:2)
在我的情况下,window.open
是在角度promise
内启动的,这打开了弹出窗口阻止程序,我的解决方案是:
$scope.gotClick = function(){
var myNewTab = browserService.openNewTab();
someService.getUrl().then(
function(res){
browserService. updateTabLocation(res.url, myNewTab);
}
);
};
browserService:
this.openNewTab = function(){
var newTabWindow = $window.open();
return newTabWindow;
}
this.updateTabLocation = function(tabLocation, tab) {
if(!tabLocation){
tab.close();
}
tab.location.href = tabLocation;
}
这是您使用promise
响应打开新标签而不是调用弹出窗口拦截器的方法。
答案 4 :(得分:1)
这是我的网站之一,使用的是普通JavaScript solution,可绕过Chrome中的弹出窗口阻止程序。
让我们说我们有以下HTML按钮:
<button id="clickMe">Click Me!</button>
现在,当用户单击按钮时,您应该做的第一件事是打开一个空的新窗口。 Fetch请求完成后,更新实际的窗口URL。如果请求失败,只需关闭窗口:
const button = document.querySelector('#clickMe');
// add click event listener
button.addEventListener('click', () => {
// open an empty window
const tab = window.open('about:blank');
// make an API call
fetch('https://reqres.in/api/users')
.then(res => res.json())
.then(json => {
// TODO: do something with JSON response
// update the actual URL
tab.location = 'https://attacomsian.com';
tab.focus();
})
.catch(err => {
// close the empty window
tab.close();
});
});
答案 5 :(得分:0)
之前的解决方案对我不起作用,但我基于它并使用了命名窗口。
internalCounter++;
var tabbedWin = window.open('','windowName_'+internalCounter);
$.ajax({
url: url,
async: false,
indexValue:internalCounter,
success: function(){
var w= window.open(url, 'windowName_'+this.indexValue);
w.focus();
}
})
答案 6 :(得分:0)
我使用这种方法:
window.location.href = window.location.protocol + '//' +
window.location.host + window.location.pathname +
"?download=" + encodeURIComponent(urlToDownload)
function param(name){
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (!results) { return 0; }
return results[1] || 0;
}
var downloadParam = param('download');
if (downloadParam) {
window.location = decodeURIComponent(downloadParam);
}