Deploy to git-pages / deploy (push) Successful in 20s
- Add VITE_PROXY_URL env var to route requests through a CORS proxy when deployed as static site (CRDC API doesn't send Access-Control-Allow-Origin) - Update useApi.js, LoadingAnimation.jsx, and ChartPanel.jsx to respect proxy - Add nginx.conf with /api/v1/ reverse proxy + CORS headers for Docker deployment - Include proxy.php — simple PHP CORS proxy for git-pages hosts that support PHP - Document CORS workaround in README Without this fix, browser fetch() calls are blocked by same-origin policy and the app shows a blank white screen despite serving correct HTML.
58 lines
1.8 KiB
PHP
58 lines
1.8 KiB
PHP
<?php
|
|
/**
|
|
* Simple CORS proxy for CRDC Arrest Rate API.
|
|
*
|
|
* Deploy this file to your git-pages host alongside the static site (e.g., at /crdc-demo/proxy.php).
|
|
* Then set VITE_PROXY_URL=/crdc-demo/proxy.php in your build environment.
|
|
*
|
|
* Usage: GET /proxy.php?target=/api/v1/districts?q=Denver&state=CO
|
|
*/
|
|
|
|
// Allow cross-origin requests from any origin
|
|
header('Access-Control-Allow-Origin: *');
|
|
header('Access-Control-Allow-Methods: GET, OPTIONS');
|
|
header('Access-Control-Allow-Headers: *');
|
|
header('Content-Type: application/json');
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
|
http_response_code(204);
|
|
exit;
|
|
}
|
|
|
|
// Extract and validate the target path from query string
|
|
$target = isset($_GET['target']) ? $_GET['target'] : '';
|
|
if (empty($target)) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Missing "target" parameter']);
|
|
exit;
|
|
}
|
|
|
|
// Construct the full API URL — only allow requests to crdc-api.civilytics.org for security
|
|
$apiBase = 'https://crdc-api.civilytics.org';
|
|
$url = $apiBase . $target;
|
|
|
|
// Validate that we're not proxying arbitrary URLs (prevent SSRF)
|
|
if (!str_starts_with($url, $apiBase . '/api/v1/')) {
|
|
http_response_code(403);
|
|
echo json_encode(['error' => 'Invalid target — must be under /api/v1/']);
|
|
exit;
|
|
}
|
|
|
|
// Fetch the API response and return it with CORS headers
|
|
$ch = curl_init($url);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_TIMEOUT => 30,
|
|
CURLOPT_SSL_VERIFYPEER => false,
|
|
]);
|
|
|
|
$response = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
|
|
// Forward the response with appropriate status code and CORS headers
|
|
http_response_code($httpCode);
|
|
header('Access-Control-Allow-Origin: *');
|
|
echo $response;
|