cors / index.html
abeea's picture
Update index.html
f4c6745 verified
Raw
History Blame Contribute Delete
7.75 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Client Frontend - CORS Lab</title>
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;800&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
<style>
:root {
--bg: #020617;
--bg-gradient: radial-gradient(circle at top right, #1e1b4b 0%, #020617 100%);
--glass: rgba(255, 255, 255, 0.03);
--glass-border: rgba(255, 255, 255, 0.1);
--primary: #3b82f6;
--primary-hover: #2563eb;
--accent: #8b5cf6;
--text: #f8fafc;
--text-muted: #94a3b8;
--success: #10b981;
--danger: #f43f5e;
--warning: #f59e0b;
}
* { box-sizing: border-box; }
body {
margin: 0;
padding: 0;
font-family: 'Outfit', sans-serif;
background: var(--bg-gradient);
color: var(--text);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.container {
width: 100%;
max-width: 1100px;
padding: 2rem;
}
.header-text {
text-align: center;
margin-bottom: 2rem;
}
h1 {
font-size: 2.5rem;
margin: 0 0 0.5rem 0;
background: linear-gradient(to right, #60a5fa, #a78bfa);
-webkit-background-clip: text;
color: transparent;
}
.grid {
display: grid;
grid-template-columns: 1fr 1.5fr;
gap: 2rem;
}
@media (max-width: 768px) {
.grid { grid-template-columns: 1fr; }
}
.card {
background: var(--glass);
backdrop-filter: blur(12px);
border: 1px solid var(--glass-border);
border-radius: 16px;
padding: 2rem;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.5);
}
h3 { margin-top: 0; margin-bottom: 1.5rem; font-weight: 600; display: flex; align-items: center; gap: 10px; }
.badge {
font-family: 'JetBrains Mono';
font-size: 0.75rem;
padding: 0.2rem 0.5rem;
background: rgba(255,255,255,0.1);
border-radius: 4px;
}
label {
display: block;
margin-bottom: 0.5rem;
font-size: 0.9rem;
color: var(--text-muted);
}
input {
width: 100%;
background: rgba(0,0,0,0.4);
border: 1px solid rgba(255,255,255,0.2);
color: #fff;
padding: 0.9rem;
border-radius: 8px;
margin-bottom: 1.5rem;
font-family: 'JetBrains Mono', monospace;
outline: none;
transition: 0.3s ease;
}
input:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(139, 92, 246, 0.3); }
.btn-group {
display: flex;
flex-direction: column;
gap: 1rem;
}
button {
width: 100%;
background: var(--primary);
color: #white;
border: none;
padding: 1rem;
border-radius: 8px;
font-family: 'Outfit', sans-serif;
font-size: 1rem;
font-weight: 600;
color: white;
cursor: pointer;
transition: 0.2s ease;
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
}
button:hover {
background: var(--primary-hover);
transform: translateY(-2px);
}
button.secondary {
background: rgba(255,255,255,0.05);
border: 1px solid rgba(255,255,255,0.1);
}
button.secondary:hover { background: rgba(255,255,255,0.1); }
.terminal {
background: #000;
border-radius: 12px;
border: 1px solid #333;
padding: 1rem;
font-family: 'JetBrains Mono', monospace;
font-size: 0.85rem;
width: 100%;
overflow-x: auto;
min-height: 150px;
color: var(--text-muted);
}
.success { color: var(--success); }
.error { color: var(--danger); text-shadow: 0 0 10px rgba(244, 63, 94, 0.5); }
.warning { color: var(--warning); }
.info { color: #60a5fa; }
</style>
</head>
<body>
<div class="container">
<div class="header-text">
<h1>Frontend Client App</h1>
<p style="color: var(--text-muted);">Making cross-origin requests to your API backend.</p>
</div>
<div class="grid">
<!-- LEFT PANEL: CONFIG & DATA -->
<div class="card">
<h3>βš™οΈ Configuration</h3>
<label>API Endpoint (Backend URL)</label>
<input id="url" value="http://localhost:5000">
<label>x-api-key</label>
<input id="key" type="password" placeholder="Paste API Key here...">
<hr style="border: 1px solid var(--glass-border); margin: 2rem 0;">
<h3>πŸ‘€ Payload Data</h3>
<label>Name</label>
<input id="name" placeholder="John Doe">
<label>Email</label>
<input id="email" placeholder="john@example.com">
<div class="btn-group">
<button onclick="send()">πŸš€ POST /api/add-user</button>
<button class="secondary" onclick="getUsers()">πŸ“₯ GET /api/users</button>
</div>
</div>
<!-- RIGHT PANEL: TERMINAL & LOGS -->
<div class="card" style="display: flex; flex-direction: column;">
<h3>πŸ’» Network Inspector <span class="badge" id="originBadge"></span></h3>
<label>Request Payload (Sent to server):</label>
<div class="terminal" id="reqBox" style="min-height: 80px; margin-bottom: 1.5rem;">{}</div>
<label>Response / Errors:</label>
<div class="terminal" id="resBox" style="flex-grow: 1;">Waiting for request...</div>
</div>
</div>
</div>
<script>
// Set Current Origin for display
document.getElementById('originBadge').innerText = "Origin: " + window.location.origin;
function logReq(data) {
document.getElementById('reqBox').innerText = JSON.stringify(data, null, 2);
}
function logRes(msg, type="info") {
const box = document.getElementById('resBox');
box.className = 'terminal ' + type;
box.innerHTML = msg;
}
function buildHeaders() {
return {
"Content-Type": "application/json",
"x-api-key": document.getElementById('key').value
};
}
async function send() {
const url = document.getElementById('url').value;
const payload = {
name: document.getElementById('name').value,
email: document.getElementById('email').value
};
logReq(payload);
logRes("Sending POST request...", "warning");
try {
const res = await fetch(`${url}/api/add-user`, {
method: "POST",
headers: buildHeaders(),
body: JSON.stringify(payload)
});
const text = await res.text();
if (!res.ok) throw new Error(`HTTP ${res.status}: ${text}`);
logRes("βœ… Success:\n" + text, "success");
} catch (err) {
handleFetchError(err);
}
}
async function getUsers() {
const url = document.getElementById('url').value;
logReq({ "action": "GET request (no body)" });
logRes("Sending GET request...", "warning");
try {
const res = await fetch(`${url}/api/users`, {
method: "GET",
headers: buildHeaders()
});
const text = await res.text();
if (!res.ok) throw new Error(`HTTP ${res.status}: ${text}`);
logRes("πŸ“₯ Users:\n" + text, "success");
} catch (err) {
handleFetchError(err);
}
}
function handleFetchError(err) {
// fetch throws a TypeError for network errors, which includes CORS blocks
if (err.name === 'TypeError' || err.message.includes('Failed to fetch')) {
logRes(`🚨 <b>CORS / Network Error!</b>\n\nThe browser blocked the request or the server is down.\n\nCheck the browser console (F12) for exact CORS details.\n\nIf it's a CORS issue, ensure <b>${window.location.origin}</b> is added to the Allowed Origins on the API Dashboard!`, 'error');
} else {
logRes(`❌ <b>Error:</b>\n` + err.message, 'error');
}
}
</script>
</body>
</html>