- HTML5 getUserMedia로 카메라 촬영 지원 (모바일 후면 카메라 기본) - 1:1 가이드 박스 UI로 정사각형 크롭 안내 - 백엔드: PIL로 800x800 리사이즈 + 썸네일 생성 - 기존 URL 교체 기능과 탭 방식으로 통합 버그 수정: - closeReplaceModal() 호출 전 변수 복사로 null 전송 문제 해결 - None 값 방어 코드 추가 Docs: TROUBLESHOOTING-CAMERA-UPLOAD.md 추가
75 lines
2.4 KiB
Markdown
75 lines
2.4 KiB
Markdown
# 트러블슈팅: 카메라 촬영 이미지 업로드 실패
|
|
|
|
## 📅 발생일: 2026-03-04
|
|
|
|
## 🔴 증상
|
|
- 제품 이미지 관리 페이지에서 "촬영" 기능으로 이미지 교체 시 저장 실패
|
|
- 에러 메시지: `NoneType object has no attribute 'strip'`
|
|
- API 호출은 성공하나 이미지 데이터가 `null`로 전송됨
|
|
|
|
## 🔍 원인 분석
|
|
|
|
### 1차 원인: None 값 처리 누락 (백엔드)
|
|
```python
|
|
# 문제 코드
|
|
image_data = data.get('image_data', '').strip() # None이면 에러
|
|
|
|
# 수정 코드
|
|
image_data = (data.get('image_data') or '').strip()
|
|
```
|
|
|
|
### 2차 원인: 변수 리셋 타이밍 문제 (프론트엔드) ⭐ 핵심
|
|
```javascript
|
|
// 문제 코드
|
|
async function submitCapture() {
|
|
const barcode = replaceTargetBarcode;
|
|
const productName = replaceTargetName;
|
|
closeReplaceModal(); // ← 여기서 capturedImageData = null 로 리셋됨!
|
|
|
|
// API 호출 시 capturedImageData가 이미 null
|
|
body: JSON.stringify({
|
|
image_data: capturedImageData, // null!
|
|
...
|
|
})
|
|
}
|
|
|
|
// 수정 코드
|
|
async function submitCapture() {
|
|
const barcode = replaceTargetBarcode;
|
|
const productName = replaceTargetName;
|
|
const imageData = capturedImageData; // ← 미리 복사!
|
|
|
|
closeReplaceModal();
|
|
|
|
body: JSON.stringify({
|
|
image_data: imageData, // 복사된 값 사용
|
|
...
|
|
})
|
|
}
|
|
```
|
|
|
|
### 3차 원인: 브라우저 캐시
|
|
- 코드 수정 후에도 브라우저가 이전 JS를 캐시
|
|
- **Ctrl+Shift+R** (강력 새로고침) 필요
|
|
|
|
## ✅ 해결 방법
|
|
|
|
1. **백엔드**: `None` 값에 대한 방어 코드 추가
|
|
2. **프론트엔드**: `closeReplaceModal()` 호출 전에 필요한 변수들을 로컬 변수로 복사
|
|
3. **테스트 시**: 강력 새로고침 (Ctrl+Shift+R) 또는 시크릿 모드 사용
|
|
|
|
## 📝 교훈
|
|
|
|
1. **모달 닫기 함수에서 상태 리셋 주의**
|
|
- 모달을 닫으면서 관련 변수를 초기화하는 경우, async 함수에서 순서에 주의
|
|
|
|
2. **프론트엔드 디버깅 시 브라우저 캐시 확인**
|
|
- 코드 수정 후에도 동작이 같다면 캐시 문제 의심
|
|
|
|
3. **API 직접 테스트로 문제 범위 좁히기**
|
|
- `requests` 또는 `curl`로 API만 테스트하면 프론트/백엔드 문제 구분 가능
|
|
|
|
## 🔧 관련 파일
|
|
- `backend/app.py` - `/api/admin/product-images/<barcode>/upload` 엔드포인트
|
|
- `backend/templates/admin_product_images.html` - 카메라 촬영 UI 및 JS
|