Files
lunchpick/lib/data/api/naver/naver_proxy_client.dart
JiWoong Sul 85fde36157 feat: 초기 프로젝트 설정 및 LunchPick 앱 구현
LunchPick(오늘 뭐 먹Z?) Flutter 앱의 초기 구현입니다.

주요 기능:
- 네이버 지도 연동 맛집 추가
- 랜덤 메뉴 추천 시스템
- 날씨 기반 거리 조정
- 방문 기록 관리
- Bluetooth 맛집 공유
- 다크모드 지원

기술 스택:
- Flutter 3.8.1+
- Riverpod 상태 관리
- Hive 로컬 DB
- Clean Architecture

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 19:03:28 +09:00

101 lines
2.9 KiB
Dart

import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import '../../../core/network/network_client.dart';
import '../../../core/network/network_config.dart';
import '../../../core/errors/network_exceptions.dart';
/// 네이버 프록시 클라이언트
///
/// 웹 환경에서 CORS 문제를 해결하기 위한 프록시 클라이언트입니다.
class NaverProxyClient {
final NetworkClient _networkClient;
NaverProxyClient({NetworkClient? networkClient})
: _networkClient = networkClient ?? NetworkClient();
/// 웹 환경에서 프록시를 통해 HTML 가져오기
Future<String> fetchViaProxy(String url) async {
if (!kIsWeb) {
throw UnsupportedError('프록시는 웹 환경에서만 사용 가능합니다');
}
try {
final proxyUrl = NetworkConfig.getCorsProxyUrl(url);
debugPrint('Using proxy URL: $proxyUrl');
final response = await _networkClient.get<String>(
proxyUrl,
options: Options(
responseType: ResponseType.plain,
headers: {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'ko-KR,ko;q=0.9,en;q=0.8',
},
),
);
if (response.data == null || response.data!.isEmpty) {
throw ParseException(
message: '프록시 응답이 비어있습니다',
);
}
return response.data!;
} on DioException catch (e) {
debugPrint('Proxy fetch error: ${e.message}');
debugPrint('Status code: ${e.response?.statusCode}');
debugPrint('Response: ${e.response?.data}');
if (e.response?.statusCode == 403) {
throw ServerException(
message: 'CORS 프록시 접근이 거부되었습니다. 잠시 후 다시 시도해주세요.',
statusCode: 403,
originalError: e,
);
}
throw ServerException(
message: '프록시를 통한 페이지 로드에 실패했습니다',
statusCode: e.response?.statusCode ?? 500,
originalError: e,
);
}
}
/// 프록시 상태 확인
Future<bool> checkProxyStatus() async {
if (!kIsWeb) {
return true; // 웹이 아니면 프록시 불필요
}
try {
final testUrl = 'https://map.naver.com';
final proxyUrl = NetworkConfig.getCorsProxyUrl(testUrl);
final response = await _networkClient.head(
proxyUrl,
options: Options(
validateStatus: (status) => status! < 500,
),
);
return response.statusCode == 200;
} catch (e) {
debugPrint('Proxy status check failed: $e');
return false;
}
}
/// 프록시 URL 생성
String getProxyUrl(String originalUrl) {
if (!kIsWeb) {
return originalUrl;
}
return NetworkConfig.getCorsProxyUrl(originalUrl);
}
void dispose() {
// 필요시 리소스 정리
}
}