Fix Download: Saubere Trennung JSON (1-3) vs ZIP (4+) Response

- 1-3 Bilder: normales AJAX ohne blob, JSON-Response direkt parsen
- 4+ Bilder: nativer XMLHttpRequest mit blob fuer ZIP-Download
- Fehler-Handler zeigt jetzt den echten Server-Fehler an
  (vorher war xhr.responseJSON immer undefined wegen blob)
- ZIP-Fehler: Blob wird als Text gelesen und JSON geparst
- Download-Dateiname aus URL extrahiert statt leer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kroonk
2026-04-16 23:52:47 +02:00
parent b65ade8381
commit 95f2847155
2 changed files with 56 additions and 34 deletions

View File

@@ -394,34 +394,43 @@
// Download-Button (direkt gebunden, nicht delegiert)
$toolbar.on('click', '#sel-download', function() {
if (selectedImages.length === 0) return;
$.ajax({
url: '/api/download/selected',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ images: selectedImages }),
xhrFields: { responseType: 'blob' },
success: function(data, status, xhr) {
var ct = xhr.getResponseHeader('Content-Type');
if (ct && ct.indexOf('application/json') !== -1) {
var reader = new FileReader();
reader.onload = function() {
var resp = JSON.parse(this.result);
if (resp.mode === 'individual') {
resp.urls.forEach(function(url, i) {
setTimeout(function() {
var a = document.createElement('a');
a.href = url;
a.download = '';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}, i * 300);
});
}
};
reader.readAsText(data);
} else {
var url = window.URL.createObjectURL(data);
var payload = JSON.stringify({ images: selectedImages });
if (selectedImages.length <= 3) {
// 1-3 Bilder: normales AJAX, Server gibt JSON mit URLs
$.ajax({
url: '/api/download/selected',
type: 'POST',
contentType: 'application/json',
data: payload,
success: function(resp) {
if (resp.mode === 'individual') {
resp.urls.forEach(function(url, i) {
setTimeout(function() {
var a = document.createElement('a');
a.href = url;
a.download = url.split('/').pop();
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}, i * 500);
});
}
},
error: function(xhr) {
var msg = (xhr.responseJSON && xhr.responseJSON.error) || 'Download fehlgeschlagen';
alert(msg);
}
});
} else {
// 4+ Bilder: Blob-Download fuer ZIP
var xhr = new XMLHttpRequest();
xhr.open('POST', '/api/download/selected', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.responseType = 'blob';
xhr.onload = function() {
if (xhr.status === 200) {
var url = window.URL.createObjectURL(xhr.response);
var a = document.createElement('a');
a.href = url;
a.download = 'mischkomposition-auswahl.zip';
@@ -429,12 +438,25 @@
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
} else {
// Fehler-Blob als Text lesen
var reader = new FileReader();
reader.onload = function() {
try {
var resp = JSON.parse(this.result);
alert(resp.error || 'Download fehlgeschlagen');
} catch(e) {
alert('Download fehlgeschlagen (Status ' + xhr.status + ')');
}
};
reader.readAsText(xhr.response);
}
},
error: function(xhr) {
alert(xhr.responseJSON ? xhr.responseJSON.error : 'Download fehlgeschlagen');
}
});
};
xhr.onerror = function() {
alert('Netzwerkfehler beim Download');
};
xhr.send(payload);
}
});
// Abbrechen-Button (direkt gebunden)

File diff suppressed because one or more lines are too long