From 1d39a2673ba9303c64be8f8032487dc16eb3dca1 Mon Sep 17 00:00:00 2001 From: Alex Kanunnikov Date: Tue, 10 Mar 2026 09:59:28 +0000 Subject: [PATCH] Add CORS fallback to getPictureForWordAsDataURL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When external image servers don't support CORS, canvas conversion fails and images don't display. Instead of rejecting with null, fall back to the original URL so images always render — just without uploading. Co-Authored-By: Claude Opus 4.6 --- frontend/app/services/image-locator.ts | 25 +++++++++++++++---------- frontend/app/services/network.ts | 3 +++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/frontend/app/services/image-locator.ts b/frontend/app/services/image-locator.ts index ab942aa2d..0ec8dbc02 100644 --- a/frontend/app/services/image-locator.ts +++ b/frontend/app/services/image-locator.ts @@ -14,21 +14,26 @@ export default class ImageLocatorService extends Service { if (!url) { return null; } - return new Promise((resolve, reject) => { + return new Promise((resolve) => { const img = new Image(); img.crossOrigin = 'anonymous'; img.src = url; img.onload = () => { - const canvas = document.createElement('canvas'); - canvas.width = img.width; - canvas.height = img.height; - const ctx = canvas.getContext('2d'); - ctx?.drawImage(img, 0, 0); - const dataURL = canvas.toDataURL('image/png'); - this.maybeUploadImage(word, canvas); - resolve(dataURL); + try { + const canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + const ctx = canvas.getContext('2d'); + ctx?.drawImage(img, 0, 0); + const dataURL = canvas.toDataURL('image/png'); + this.maybeUploadImage(word, canvas); + resolve(dataURL); + } catch { + // tainted canvas (CORS headers present but insufficient) + resolve(url); + } }; - img.onerror = () => reject(null); + img.onerror = () => resolve(url); }); } private maybeUploadImage(word: string, canvas: HTMLCanvasElement): void { diff --git a/frontend/app/services/network.ts b/frontend/app/services/network.ts index 2216ceded..9efa425d5 100644 --- a/frontend/app/services/network.ts +++ b/frontend/app/services/network.ts @@ -250,6 +250,9 @@ export default class NetworkService extends Service { } } uploadPictureFile(file: Blob, fileName: string): Promise { + if (!file.size) { + return Promise.reject(new Error('Empty file')); + } const formData = new FormData(); formData.append('file', file, fileName); return waitForPromise(