Skip to content

Commit 73eb031

Browse files
authored
Add index.html for Perchance Generator with CORS
1 parent 3687902 commit 73eb031

1 file changed

Lines changed: 96 additions & 0 deletions

File tree

index.html

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Perchance Generator – Fixed with CORS proxy</title>
6+
<style>
7+
body { font-family: system-ui, Arial, sans-serif; max-width: 800px; margin: 2rem auto; padding: 0 20px; }
8+
#output { padding: 1rem; border: 1px solid #ccc; border-radius: 12px; min-height: 80px; margin: 1rem 0; background: #f9f9fc; }
9+
button, input { padding: 8px 14px; font-size: 1rem; border-radius: 40px; border: 1px solid #aaa; }
10+
button { background: #1e2f3e; color: white; cursor: pointer; transition: 0.2s; }
11+
button:hover { background: #0f1e2a; }
12+
.error { color: #c33; background: #ffe8e6; padding: 0.5rem; border-radius: 12px; }
13+
.success { background: #e0f2e9; padding: 0.5rem; border-radius: 12px; }
14+
hr { margin: 1.5rem 0; }
15+
code { background: #eee; padding: 0.2rem 0.4rem; border-radius: 8px; }
16+
small { display: block; margin-top: 1rem; color: #555; }
17+
</style>
18+
</head>
19+
<body>
20+
<h1>🎲 Perchance Generator (CORS fixed)</h1>
21+
<p>Uses <code>corsproxy.io</code> to bypass CORS restrictions.</p>
22+
23+
<label for="generatorInput"><strong>Generator name:</strong> (e.g. <code>fantasy-character</code>, <code>tavern-names</code>)</label><br>
24+
<input type="text" id="generatorInput" value="fantasy-character" style="width: 70%; margin-top: 6px;">
25+
26+
<div id="output">✨ Click "Generate" to see a random result.</div>
27+
<button id="generateBtn">Generate</button>
28+
29+
<hr>
30+
<small>🔧 Proxy: <code>https://corsproxy.io/</code> → forwards request to Perchance API. No backend required.</small>
31+
32+
<script>
33+
const generateBtn = document.getElementById('generateBtn');
34+
const generatorInput = document.getElementById('generatorInput');
35+
const outputDiv = document.getElementById('output');
36+
37+
async function fetchFromPerchance() {
38+
const generatorName = generatorInput.value.trim();
39+
if (!generatorName) {
40+
outputDiv.innerHTML = '<span class="error">❌ Please enter a generator name.</span>';
41+
return;
42+
}
43+
44+
// Direct API URL (without proxy – would cause CORS error)
45+
const directApiUrl = `https://perchance.org/api/generate?generator=${encodeURIComponent(generatorName)}&count=1`;
46+
47+
// CORS proxy that works with perchance.org
48+
const proxyUrl = `https://corsproxy.io/?${encodeURIComponent(directApiUrl)}`;
49+
50+
generateBtn.disabled = true;
51+
generateBtn.textContent = '⏳ Loading...';
52+
outputDiv.innerHTML = '🌀 Fetching via proxy...';
53+
54+
try {
55+
const controller = new AbortController();
56+
const timeoutId = setTimeout(() => controller.abort(), 10000);
57+
const response = await fetch(proxyUrl, { signal: controller.signal });
58+
clearTimeout(timeoutId);
59+
60+
if (!response.ok) {
61+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
62+
}
63+
64+
const data = await response.json();
65+
66+
if (Array.isArray(data) && data.length > 0 && typeof data[0] === 'string') {
67+
outputDiv.innerHTML = `<div class="success">✨ ${escapeHtml(data[0])}</div>`;
68+
} else {
69+
outputDiv.innerHTML = '<span class="error">⚠️ Unexpected response format. Try another generator.</span>';
70+
}
71+
} catch (err) {
72+
console.error(err);
73+
let msg = err.message;
74+
if (err.name === 'AbortError') msg = 'Timeout – proxy/server took too long.';
75+
else if (msg.includes('Failed to fetch')) msg = 'Network error – proxy may be blocked. Try reloading or use a different proxy.';
76+
outputDiv.innerHTML = `<span class="error">❌ ${escapeHtml(msg)}</span>`;
77+
} finally {
78+
generateBtn.disabled = false;
79+
generateBtn.textContent = 'Generate';
80+
}
81+
}
82+
83+
function escapeHtml(str) {
84+
return str.replace(/[&<>]/g, function(m) {
85+
if (m === '&') return '&amp;';
86+
if (m === '<') return '&lt;';
87+
if (m === '>') return '&gt;';
88+
return m;
89+
});
90+
}
91+
92+
generateBtn.addEventListener('click', fetchFromPerchance);
93+
generatorInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') fetchFromPerchance(); });
94+
</script>
95+
</body>
96+
</html>

0 commit comments

Comments
 (0)