feat: Vercel serverless proxy for Dropbox (fix deploy issues) && update App.tsx

This commit is contained in:
Christian Vidal Wolf
2026-01-16 10:50:39 +01:00
parent a1ad3aa944
commit e271d9d5ba
4 changed files with 1906 additions and 17 deletions
+6 -12
View File
@@ -61,22 +61,16 @@ const App: React.FC = () => {
directUrl = urlObject.toString();
}
let fetchUrl = directUrl;
// Check if we are in a local environment to use the Vite proxy
const isLocal = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
// Unified Fetch Logic for Local (Vite) and Production (Vercel Function)
// Both environments now support the /api/dropbox/... path.
// - Local: Vite proxies /api/dropbox -> https://www.dropbox.com
// - Vercel: api/dropbox.js handles the request -> https://www.dropbox.com
if (isLocal && url.includes('dropbox.com')) {
// Extract path and query from the direct URL
const urlObj = new URL(directUrl);
// Pass the necessary query params including st and dl=1
const searchParams = urlObj.search;
fetchUrl = `/api/dropbox${urlObj.pathname}${searchParams}`;
} else {
// Production or non-local fallback: Use CORS proxy
// Using allorigins.win as a fallback if not local
fetchUrl = `https://api.allorigins.win/raw?url=${encodeURIComponent(directUrl)}`;
}
// Construct path relative to root: /api/dropbox/scl/fi/...
const fetchUrl = `/api/dropbox${urlObj.pathname}${searchParams}`;
const response = await fetch(fetchUrl);
if (!response.ok) throw new Error(`Failed to fetch CSV from URL: ${response.status} ${response.statusText}`);
+53
View File
@@ -0,0 +1,53 @@
import type { VercelRequest, VercelResponse } from '@vercel/node';
export default async function handler(req: VercelRequest, res: VercelResponse) {
// Allow CORS
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,OPTIONS,PATCH,DELETE,POST,PUT');
res.setHeader(
'Access-Control-Allow-Headers',
'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version'
);
if (req.method === 'OPTIONS') {
res.status(200).end();
return;
}
try {
// 1. Reconstruct the Target Dropbox URL
// The incoming request is to /api/dropbox/scl/fi/...
// We want to fetch https://www.dropbox.com/scl/fi/...
// req.url in Vercel function might be just the suffix or full path depending on routing
// Typically: /api/dropbox/scl/fi/xyz?dl=1
// We need to strip '/api/dropbox' from the start to get the dropbox path
const requestPath = req.url || '';
const dropboxPath = requestPath.replace(/^\/api\/dropbox/, ''); // e.g. /scl/fi/xyz?dl=1
const targetUrl = `https://www.dropbox.com${dropboxPath}`;
console.log(`Proxying to: ${targetUrl}`);
const response = await fetch(targetUrl);
if (!response.ok) {
throw new Error(`Dropbox responded with ${response.status} ${response.statusText}`);
}
// Forward the content type (likely text/csv)
const contentType = response.headers.get('content-type');
if (contentType) {
res.setHeader('Content-Type', contentType);
}
const data = await response.text();
res.status(200).send(data);
} catch (error) {
console.error('Proxy Error:', error);
res.status(500).json({ error: 'Failed to fetch data from Dropbox' });
}
}
+1841
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -9,15 +9,16 @@
"preview": "vite preview"
},
"dependencies": {
"@google/genai": "^1.30.0",
"papaparse": "^5.5.3",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"@google/genai": "^1.30.0",
"recharts": "^3.5.0",
"xlsx": "^0.18.5",
"papaparse": "^5.5.3"
"xlsx": "^0.18.5"
},
"devDependencies": {
"@types/node": "^22.14.0",
"@vercel/node": "^5.5.22",
"@vitejs/plugin-react": "^5.0.0",
"typescript": "~5.8.2",
"vite": "^6.2.0"