(从服务器故障重新发布)
我对 JavaScript 开发还很陌生。
我有一个 PHP/HTML 网页,用户可以在其中编辑内容,完成后,他们单击“保存”,它将更改保存到数据库中。这很好用,但我实现的是 html2canvas 保存当前状态的渲染图像,并将其显示在另一个页面上。
我的问题是:渲染和保存现在需要大约 15 秒才能保存图像文件。如果用户在此完成之前关闭选项卡,渲染当然会中断。因此,我决定显示一条消息“请等待渲染”,渲染完成后该消息将关闭。 但我无法等到渲染完成 - 我已经阅读了很多有关 Promise、async、await 等内容的内容,但我还没有完全理解该功能。
这是我的代码:
const saveButton = document.getElementById('saveButton');
saveButton.addEventListener('click', saveChanges);
function saveChanges() {
// here is the code for saving data to database ...
// then the image will be rendered
console.log('Start image generating')
showSaveMessage('Öffentliche Ansicht wird generiert...'); // This creates a message box
// setTimeout is needed, because otherwise somehow, the rendering is missing texts etc.
setTimeout(() => {
html2canvas(document.getElementById('map'), {
onclone: function(document) {
// do some CSS changes before rendering
});
},
scale: 2,
useCORS: true,
}).then(canvas => {
console.log('Starting to convert');
const imgData = canvas.toDataURL('image/png');
fetch('sources/saveimage.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ imageData: imgData })
});
console.log('Conversion done');
});
}, 200);
hideSaveMessage(); // This closes the message box
}
目前,消息框在打开后立即关闭,因此它实际上并不等待渲染和保存图像。我还尝试在 fetch 之后添加
.then
,但它会在 1-2 秒内关闭消息,而 PHP 需要 10-15 秒才能真正完成图像保存。
我的 PHP 非常简单:
<?php
$data = file_get_contents('php://input');
// error_log($data);
$image = explode('base64,',$data);
file_put_contents('images/glencore/rendered.png', base64_decode($image[1]));
?>
也许你们中的一些人能够解决这个问题并向我解释:-)
您的目标似乎是阻止用户在 PDF 创建完成之前离开页面。
要实现此目的,您可以使用
beforeunload
事件向用户显示警告警报,告知用户进程仍在运行,如果他们过早离开页面,将会受到影响。不幸的是,您无法修改通知中显示的文本,但希望它足以提示用户等待。
这是如何实现的演示。如果您单击“保存”按钮,然后尝试单击链接以离开该页面,浏览器将要求您确认该操作。 PDF 生成完成后,用户将可以像平常一样自由导航。
const showSaveMessage = msg => document.querySelector('#message').textContent = msg;
const hideSaveMessage = () => document.querySelector('#message').hidden = true;
let pdfGenerationInProgress = false;
const saveButton = document.getElementById('saveButton');
saveButton.addEventListener('click', saveChanges);
function saveChanges() {
console.log('Start image generating')
showSaveMessage('Öffentliche Ansicht wird generiert...');
pdfGenerationInProgress = true;
setTimeout(() => {
// generate the PDF here...
console.log('Conversion done');
pdfGenerationInProgress = false
}, 5000);
hideSaveMessage();
}
window.addEventListener('beforeunload', () => {
if (pdfGenerationInProgress) {
event.preventDefault();
event.returnValue = '';
}
})
<div id="message"></div>
<button id="saveButton">Save PDF</button>
<a href="https://google.com">Leave page...</a>
值得注意的是,这绝不是一个万无一失的解决方案。如果可能的话,更好的方法是生成文件服务器端,以便用户在生成文件时可以随意浏览您的网站,然后在文件准备好访问时通知他们 - 通过 websockets 或通过电子邮件向他们发送下载链接。