javascript - 使用 window.open 检测“php://output”的完成
问题描述
我使用PhpSpreadsheet以这种方式导出 mysql 数据:
第 1 页:
button
触发window.open
到带有导出脚本的页面
window.open('/export.php?data.., '_self');
第 2 页(export.php):
整个系统的出口和php://output
ob_end_clean();
ob_start();
$objWriter->save('php://output');
exit;
我可以以某种方式了解导出页面是否已完成?我需要这个来触发覆盖。
我试过什么?
查看stackoverflow我尝试了这个解决方案,但没有奏效:
overlay.style.display = "block";
let myPopup = window.open('/export.php?data.., '_self');
myPopup.addEventListener('load', () => {
console.log('load'); //just for debug
overlay.style.display = "none";
}, false);
解决方案
这将执行一个 ajax 请求,这将导致下载而不用 jQuery 刷新页面
<button id='download'>Download Spreadsheet</button>
<form method='get' action='/export.php?' id='hiddenForm'>
<input type='hidden' name='foo' value='bar' />
<input type='hidden' name='foo2' value='bar2' />
</form>
$(document).on('click', '#download', function (e) {
e.preventDefault();
$('#hiddenForm').submit();
});
确保您的 PHP 输出正确的内容类型
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
另外一个选项
根据这篇文章,没有可用于真正检测跨所有不同浏览器加载 javascript 窗口对象的 api。此方法使用延迟回调和postMessage
方法来适应大多数现代浏览器。
function defer (callback) {
var channel = new MessageChannel();
channel.port1.onmessage = function (e) {
callback();
};
channel.port2.postMessage(null);
}
var awaitLoad = function (win, cb){
var wasCalled = false;
function unloadListener(){
if (wasCalled)
return;
wasCalled = true;
win.removeEventListener("unload", unloadListener);
win.removeEventListener("pagehide", unloadListener);
// Firefox keeps window event listeners for multiple page loads
defer(function (){
win.document.readyState;
// IE sometimes throws security error if not accessed 2 times
if (win.document.readyState === "loading")
win.addEventListener("load", function loadListener(){
win.removeEventListener("load", loadListener);
cb();
});
else
cb();
});
};
win.addEventListener("unload", unloadListener);
win.addEventListener("pagehide", unloadListener);
// Safari does not support unload
}
w = window.open();
w.location.href="/export.php?data=foo";
awaitLoad(w, function (){
console.log('got it')
});
推荐阅读
- ios - 回避 iOS13 Native PointerEvents
- angular - 带有参数的嵌套离子角选项卡路由
- mysql - MySQL 查询优化器显示对具有主索引和复合索引的表的查询的随机行为
- python - 带有阶段的 TensorFlow 自定义训练
- mysql - MySQL 连接导致两个 varchar cols 上的 CONVERT(USING utf16)
- prolog - Prolog 查询不返回所有答案
- selenium-webdriver - 难以使用 ID、XPATH 和 CSS 定位元素
- java - 如何修复“com.spotify.android.appremote.api.error.AuthenticationFailedException”
- c# - C# 打印 Word 文档而不打开 Word 或 Printerselection
- c# - 为 Scaffold-DbContext 逆向工程定义自定义模型名称