Investigate CORS proxy failure

The CORS proxy is failing despite being enabled, resulting in REST API and database connection errors. Investigate the cause of the failure.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-15 12:23:00 +00:00
parent 893e1cf0aa
commit 1623fd7738
4 changed files with 68 additions and 16 deletions

View File

@@ -24,16 +24,25 @@ try {
flowType: 'implicit',
},
global: {
fetch: (url, options) => {
// CORS 디버깅을 위한 사용자 정의 fetch
// 커스텀 fetch 구현
fetch: (...args) => {
// 첫 번째 인자는 URL 또는 Request 객체
const urlOrRequest = args[0];
// URL 로깅 및 디버깅
let url = typeof urlOrRequest === 'string' ? urlOrRequest : urlOrRequest.url;
console.log('Supabase fetch 요청:', url);
return fetch(url, options).then(response => {
console.log('Supabase 응답 상태:', response.status);
return response;
}).catch(err => {
console.error('Supabase fetch 오류:', err);
throw err;
});
// 기본 fetch 호출
return fetch(...args)
.then(response => {
console.log('Supabase 응답 상태:', response.status);
return response;
})
.catch(err => {
console.error('Supabase fetch 오류:', err);
throw err;
});
}
}
});

View File

@@ -6,9 +6,10 @@ export const getSupabaseUrl = () => {
if (storedUrl) {
// CORS 프록시 설정 확인
const useProxy = localStorage.getItem('use_cors_proxy') === 'true';
if (useProxy && storedUrl.startsWith('http://')) {
// CORS 프록시 URL로 변환
return `https://corsproxy.io/?${encodeURIComponent(storedUrl)}`;
if (useProxy) {
// CORS 프록시 URL로 변환 (URL 구조 개선)
const cleanUrl = storedUrl.trim();
return `https://corsproxy.io/?${encodeURIComponent(cleanUrl)}`;
}
return storedUrl;
}
@@ -39,8 +40,11 @@ export const isCorsProxyEnabled = () => {
// 온프레미스 연결을 위한 설정 도우미 함수
export const configureSupabase = (url: string, key: string, useProxy: boolean = false) => {
// URL 정리 (앞뒤 공백 제거)
const cleanUrl = url.trim();
// 로컬 스토리지에 설정 저장
localStorage.setItem('supabase_url', url);
localStorage.setItem('supabase_url', cleanUrl);
localStorage.setItem('supabase_key', key);
localStorage.setItem('use_cors_proxy', useProxy.toString());

View File

@@ -42,7 +42,11 @@ export const testSupabaseConnection = async () => {
// 1. REST API 접근 테스트
try {
console.log('REST API 테스트 시작...');
const apiUrl = `${results.proxyUrl}/rest/v1/`;
// 정확한 REST API 엔드포인트 구성
const apiUrl = results.proxyUrl.endsWith('/')
? `${results.proxyUrl}rest/v1/`
: `${results.proxyUrl}/rest/v1/`;
console.log('REST API 테스트 URL:', apiUrl);
const response = await fetch(apiUrl, {

View File

@@ -3,7 +3,7 @@ import React, { useState, useEffect } from 'react';
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { DatabaseIcon, Save, RefreshCw, Shield } from "lucide-react";
import { DatabaseIcon, Save, RefreshCw, Shield, AlertTriangle, Check } from "lucide-react";
import { toast } from "@/hooks/useToast.wrapper";
import { configureSupabase, isCorsProxyEnabled } from "@/lib/supabase/config";
import { Switch } from "@/components/ui/switch";
@@ -29,6 +29,11 @@ const SupabaseSettings = () => {
setUseProxy(proxyEnabled);
}, []);
const validateUrl = (url: string): boolean => {
// URL 유효성 검사: http:// 또는 https://로 시작하는지 확인
return /^https?:\/\/.+/.test(url);
};
const handleSave = () => {
if (!supabaseUrl || !supabaseKey) {
toast({
@@ -39,6 +44,15 @@ const SupabaseSettings = () => {
return;
}
if (!validateUrl(supabaseUrl)) {
toast({
title: "URL 오류",
description: "유효한 URL 형식이 아닙니다. http:// 또는 https://로 시작하는 URL을 입력해주세요.",
variant: "destructive"
});
return;
}
setIsSaving(true);
try {
@@ -90,6 +104,9 @@ const SupabaseSettings = () => {
}
};
const isHttpsUrl = supabaseUrl.startsWith("https://");
const suggestProxy = supabaseUrl.startsWith("http://") && !useProxy;
return (
<div className="min-h-screen bg-neuro-background pb-24">
<div className="max-w-md mx-auto px-6">
@@ -114,6 +131,21 @@ const SupabaseSettings = () => {
className="pl-10 neuro-pressed"
/>
</div>
{/* URL 관련 경고 및 안내 추가 */}
{suggestProxy && (
<div className="flex items-center text-amber-500 text-xs mt-1 p-2 bg-amber-50 rounded-md">
<AlertTriangle className="h-4 w-4 mr-1 flex-shrink-0" />
<span>HTTP URL을 . CORS .</span>
</div>
)}
{isHttpsUrl && (
<div className="flex items-center text-green-500 text-xs mt-1 p-2 bg-green-50 rounded-md">
<Check className="h-4 w-4 mr-1 flex-shrink-0" />
<span>HTTPS URL을 . .</span>
</div>
)}
</div>
<div className="space-y-2">
@@ -248,7 +280,7 @@ const SupabaseSettings = () => {
<ul className="list-disc pl-5 text-sm text-gray-500 space-y-2">
<li>
<strong>Supabase URL</strong>: Supabase URL을 .
(: http://192.168.1.100:8000)
(: https://192.168.1.100:8000)
</li>
<li>
<strong>Anon Key</strong>: Supabase API anon/public .
@@ -256,6 +288,9 @@ const SupabaseSettings = () => {
<li>
<strong>CORS </strong>: HTTP URL에 . HTTPS가 URL에 .
</li>
<li className="text-amber-500 font-medium">
HTTPS URL을 . HTTP URL을 CORS .
</li>
</ul>
</div>
</div>