88 lines
No EOL
2.4 KiB
JavaScript
88 lines
No EOL
2.4 KiB
JavaScript
import { DEFAULT_CORS_PROXY } from './constants';
|
|
|
|
/**
|
|
* Fetch data with CORS proxy fallback
|
|
* @param {string} url - The URL to fetch
|
|
* @param {Object} options - Fetch options
|
|
* @returns {Promise<any>} - The fetched data
|
|
*/
|
|
export async function fetchWithCors(url, options = {}) {
|
|
const proxy = import.meta.env.REACT_APP_CORS_PROXY || DEFAULT_CORS_PROXY;
|
|
|
|
try {
|
|
// Try direct fetch first
|
|
const response = await fetch(url, {
|
|
...options,
|
|
mode: 'cors',
|
|
headers: {
|
|
...options.headers,
|
|
'Accept': 'application/json',
|
|
}
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const contentType = response.headers.get('content-type');
|
|
if (contentType && contentType.includes('application/json')) {
|
|
return await response.json();
|
|
} else {
|
|
return await response.text();
|
|
}
|
|
} catch (error) {
|
|
// If CORS fails, try with proxy
|
|
console.warn(`CORS failed for ${url}, trying proxy...`, error.message);
|
|
|
|
try {
|
|
const proxiedUrl = `${proxy}${encodeURIComponent(url)}`;
|
|
const response = await fetch(proxiedUrl, options);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const contentType = response.headers.get('content-type');
|
|
if (contentType && contentType.includes('application/json')) {
|
|
return await response.json();
|
|
} else {
|
|
return await response.text();
|
|
}
|
|
} catch (proxyError) {
|
|
console.error(`Both direct and proxy fetch failed for ${url}:`, proxyError);
|
|
throw proxyError;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test if a URL is accessible directly without CORS issues
|
|
* @param {string} url - The URL to test
|
|
* @returns {Promise<boolean>} - True if accessible, false otherwise
|
|
*/
|
|
export async function testCorsAccess(url) {
|
|
try {
|
|
const response = await fetch(url, {
|
|
method: 'HEAD',
|
|
mode: 'cors',
|
|
});
|
|
return response.ok;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the appropriate URL (direct or proxied) based on CORS accessibility
|
|
* @param {string} url - The original URL
|
|
* @returns {Promise<string>} - Either the original URL or a proxied version
|
|
*/
|
|
export async function getAccessibleUrl(url) {
|
|
const canAccess = await testCorsAccess(url);
|
|
if (canAccess) {
|
|
return url;
|
|
}
|
|
|
|
const proxy = import.meta.env.REACT_APP_CORS_PROXY || DEFAULT_CORS_PROXY;
|
|
return `${proxy}${encodeURIComponent(url)}`;
|
|
} |