Your popup is being blocked because window.open() is being called after the polling interval finishes, not directly in response to a user action.
Browsers allow popups only when they’re triggered synchronously from user gestures (e.g., click events). In your code, the setInterval callback runs asynchronously later, so the open action is no longer tied to the click that started the process — the browser flags it as an unsolicited popup.
Fix:
- Open a blank tab/window immediately when the user clicks to start polling.
- During polling, once the PDF is ready, just change the location.href of that already-open window to the Blob URL.
- This way, the “popup” is approved at the moment of the click, and the browser won’t block it when you update it later.
and here is the code.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Polling + Open PDF</title>
<script>
// Simulate API response
const Utilities = {
async PostFunction(url, fileId) {
await new Promise(resolve => setTimeout(resolve, 1000));
// Valid full base64 of a simple PDF
const base64 = "JVBERi0xLjQKMSAwIG9iago8PAovQ3JlYXRvciAoUERGIEdlbmVyYXRvcikgCi9UeXBlIC9DYXRhbG9nCi9QYWdlcyAyIDAgUgo+PgplbmRvYmoKMiAwIG9iago8PAovVHlwZSAvUGFnZXMKL0tpZHMgWzMgMCBSXQovQ291bnQgMQo+PgplbmRvYmoKMyAwIG9iago8PAovVHlwZSAvUGFnZQovUGFyZW50IDIgMCBSCi9NZWRpYUJveCBbMCAwIDYxMiA3OTJdCi9Db250ZW50cyA0IDAgUgo+PgplbmRvYmoKNCAwIG9iago8PAovTGVuZ3RoIDM3Cj4+CnN0cmVhbQpCBiAwIDAgMCAwIDAgblQKSGVsbG8gV29ybGQhIFQKRVQKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjw8Ci9UeXBlIC9YUmVmCi9XSUQgWzIgMCAgUl0KPj4KZW5kb2JqCnhyZWYKMCA2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxMCAwMDAwMCBuIAowMDAwMDAwMDE4IDAwMDAwIG4gCjAwMDAwMDAwNjUgMDAwMDAgbiAKMDAwMDAwMDAxNzUgMDAwMDAgbiAKMDAwMDAwMDAyNzYgMDAwMDAgbiAKdHJhaWxlcgo8PAovUm9vdCAxIDAgUgo+PgpzdGFydHhyZWYKMzkwCiUlRU9G";
return {
Base64EncryptedData: base64,
MimeType: "application/pdf",
FileName: "HelloWorld",
FileExtension: ".pdf"
};
}
};
const Base64ToBinary = {
decodeArrayBuffer(base64) {
const binary = atob(base64);
const len = binary.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binary.charCodeAt(i);
}
return bytes;
}
};
const DownloadReportFileURL = "https://example.com/download";
function startPollingForPdf(fileId) {
const popup = window.open('', '_blank');
if (!popup) {
alert("Popup blocked. Please allow popups.");
return;
}
popup.document.write("<h2>Generating your report...</h2>");
let tries = 0;
const interval = setInterval(async () => {
tries++;
if (tries === 5) {
clearInterval(interval);
const ret = await Utilities.PostFunction(DownloadReportFileURL, fileId);
const blob = new Blob(
[Base64ToBinary.decodeArrayBuffer(ret.Base64EncryptedData)],
{ type: ret.MimeType }
);
const blobURL = URL.createObjectURL(blob);
popup.location.href = blobURL;
// Optional: trigger download
const link = document.createElement('a');
link.href = blobURL;
link.download = ret.FileName + ret.FileExtension;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}, 1000);
}
</script>
</head>
<body>
<h2>Start polling & open PDF</h2>
<button onclick="startPollingForPdf('abc123')">Start Polling</button>
</body>
</html>
const displayWindow = window.open("placeholder-page.htm", "_blank");right away whenDownloadAndOpenPdfgets invoked via click, and thendisplayWindow.location.href = link.hreflater.