fix(backup): ссылка на архив переживает F5 и повторное скачивание
HEAD-проба в downloadBackup() сжигала одноразовый тикет: Express 4 прогоняет HEAD через GET-хендлер /api/backup/:token, который удалял тикет и файл до отдачи архива, поэтому настоящий GET всегда получал 404 «Ссылка на бэкап устарела». - server.js: GET /api/backup/:token больше не удаляет тикет и файл — ссылка живёт BACKUP_TTL_MS (30 мин), Range-докачка работает - вынес dropBackupTicket(), fs.rmSync обёрнут в try/catch - BACKUP_TICKETS_MAX = 3: лишние тикеты вычищаются по возрасту - sweepBackupStorage() режет с запасом 5 минут сверх TTL - settings.js: убрана HEAD-проба, в #backupStatus рендерится реальная кликабельная ссылка вместо невидимого синтетического <a> - AGENTS.md: раздел 8 — новое поведение + предупреждение про HEAD
This commit is contained in:
+13
-7
@@ -863,11 +863,19 @@ async function downloadBackup() {
|
||||
showError('Ошибка формирования бэкапа: ' + (data.error || res.status));
|
||||
return;
|
||||
}
|
||||
const head = await fetch(data.url, { method: 'HEAD' }).catch(() => null);
|
||||
if (head && !head.ok) {
|
||||
if (st) { st.classList.add('err'); st.textContent = 'Ссылка на архив устарела, попробуйте ещё раз'; }
|
||||
showError('Ошибка скачивания бэкапа');
|
||||
return;
|
||||
const size = formatBackupSize(data.size);
|
||||
if (st) {
|
||||
st.classList.remove('err');
|
||||
st.innerHTML = '';
|
||||
const link = document.createElement('a');
|
||||
link.href = data.url;
|
||||
link.download = data.filename || 'whatido-backup.tar.gz';
|
||||
link.textContent = data.filename || 'whatido-backup.tar.gz';
|
||||
link.style.color = 'var(--accent)';
|
||||
st.appendChild(link);
|
||||
const note = document.createElement('span');
|
||||
note.textContent = `${size ? ` (${size})` : ''} — ссылка активна 30 минут, скачивание можно повторить`;
|
||||
st.appendChild(note);
|
||||
}
|
||||
const a = document.createElement('a');
|
||||
a.href = data.url;
|
||||
@@ -875,8 +883,6 @@ async function downloadBackup() {
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
const size = formatBackupSize(data.size);
|
||||
if (st) st.textContent = `Архив ${data.filename}${size ? ` (${size})` : ''} — скачивается браузером`;
|
||||
showToast('Бэкап сформирован' + (size ? ': ' + size : ''));
|
||||
} catch (err) {
|
||||
if (st) { st.classList.add('err'); st.textContent = 'Не удалось сформировать бэкап: ' + err.message; }
|
||||
|
||||
Reference in New Issue
Block a user