fix(ocr): Fix mobile file upload ERR_NETWORK on Android/iOS

Clone file to memory immediately after selection to avoid SnapshotState
invalidation in W3C File API. Android/iOS browsers invalidate File object
references after accessing properties (name, size, type).

See: https://issues.chromium.org/40703873

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-01-05 14:22:56 +00:00
parent 13fc5e9abb
commit bb72b690ab
2 changed files with 43 additions and 3 deletions

View File

@@ -420,6 +420,30 @@ const response = await api.get('/endpoint');
**Frontend**: Clear node_modules, check Node.js version (16+), Vite auto-ports
**Database**: Verify SSH tunnel, Oracle listener, credentials, test `/health`
### Known Issues & Fixes
#### Mobile File Upload ERR_NETWORK (Android/iOS)
**Problem**: File uploads (OCR, attachments) fail with `ERR_NETWORK` (status 0) on mobile browsers, but work on desktop.
**Cause**: Android/iOS browsers invalidate File object references after accessing properties (`file.name`, `file.size`, `file.type`) due to **SnapshotState** in the W3C File API. See [Chromium Bug #40703873](https://issues.chromium.org/40703873).
**Solution**: Clone the file into memory immediately after selection, before accessing any properties:
```javascript
const handleFile = async (file) => {
// Validations first...
// FIX: Clone file to memory to avoid SnapshotState invalidation
const arrayBuffer = await file.arrayBuffer()
const clonedFile = new File([arrayBuffer], file.name, {
type: file.type,
lastModified: file.lastModified
})
selectedFile.value = clonedFile
}
```
**Applied in**: `src/modules/data-entry/components/ocr/OCRUploadZone.vue`
---
## 🔧 Tech Stack

View File

@@ -217,7 +217,7 @@ const onFileSelected = (event) => {
}
}
const handleFile = (file) => {
const handleFile = async (file) => {
// Validate file type
const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf']
if (!allowedTypes.includes(file.type)) {
@@ -232,8 +232,24 @@ const handleFile = (file) => {
}
error.value = null
selectedFile.value = file
emit('file-selected', file)
// FIX pentru Android: Clonăm fișierul în memorie IMEDIAT după selectare
// pentru a evita invalidarea referinței de către browser (SnapshotState issue)
// See: https://issues.chromium.org/40703873
try {
const arrayBuffer = await file.arrayBuffer()
const clonedFile = new File([arrayBuffer], file.name, {
type: file.type,
lastModified: file.lastModified
})
selectedFile.value = clonedFile
emit('file-selected', clonedFile)
} catch (e) {
// Fallback pentru browsere care nu suportă arrayBuffer
console.warn('File clone failed, using original:', e)
selectedFile.value = file
emit('file-selected', file)
}
}
const processOCR = async () => {