Skip to content

Instantly share code, notes, and snippets.

@thekid
Created June 7, 2026 10:37
Show Gist options
  • Select an option

  • Save thekid/7826ce31ff382f93965b7d54f1e47ee4 to your computer and use it in GitHub Desktop.

Select an option

Save thekid/7826ce31ff382f93965b7d54f1e47ee4 to your computer and use it in GitHub Desktop.
CORS testing
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CORS test</title>
<style>
form { display: grid; gap: 1rem; }
textarea { width: 100%; }
/** Simple requests w/o preflight */
#head, #get, #get-params, #get-credentials, #post { background-color: lightsteelblue; }
</style>
</head>
<body>
<form>
<textarea id="debug" rows="12"></textarea>
<fieldset>
<input type="text" id="cookie" placeholder="Cookie...">
<button type="button" id="clear">✖️</button>
</fieldset>
<fieldset>
<button type="button" id="head">HEAD /</button>
<button type="button" id="head-binford">HEAD / (X-Binford: 6100)</button>
<button type="button" id="get">GET /</button>
<button type="button" id="get-binford">GET / (X-Binford: 6100)</button>
<button type="button" id="get-params">GET /?name=tim-taylor</button>
<button type="button" id="get-credentials">GET / {credentials: include}</button>
<button type="button" id="post">POST /</button>
<button type="button" id="patch-binford">PATCH / (X-Binford: 6100)</button>
</fieldset>
</form>
<script type="module">
const $debug = document.getElementById('debug');
const execute = async function(query, options) {
const request = new Request('http://localhost:8080' + query, options);
$debug.value = `>>> ${request.method} ${request.url} HTTP/1.1\n`;
for (const [header, value] of request.headers.entries()) {
$debug.value += `${header}: ${value}\n`;
}
if (options.credentials) $debug.value += `Set-Cookie: ${document.cookie}\n`;
$debug.value += options.body ? `\n${options.body}\n\n` : `\n`;
try {
const response = await fetch(request);
$debug.value += `<<< HTTP/1.1 ${response.status} ${response.statusText}\n`;
for (const [header, value] of response.headers.entries()) {
$debug.value += `${header}: ${value}\n`;
}
$debug.value += `\n`;
$debug.value += await response.text();
$debug.value += `\n`;
} catch (e) {
$debug.value += e;
}
}
const $cookie = document.getElementById('cookie');
const user = await cookieStore.get('user');
$cookie.value = user?.value ?? '';
$cookie.addEventListener('input', e => {
cookieStore.set('user', $cookie.value);
});
document.getElementById('clear').addEventListener('click', e => {
cookieStore.delete('user');
$cookie.value = '';
});
// HEAD
document.getElementById('head').addEventListener('click', e => {
execute('', {method: 'HEAD'});
});
document.getElementById('head-binford').addEventListener('click', e => {
execute('', {method: 'HEAD', headers: {'X-Binford': '6100'}});
});
// GET
document.getElementById('get').addEventListener('click', e => {
execute('', {});
});
document.getElementById('get-params').addEventListener('click', e => {
execute('?user=tim-taylor', {});
});
document.getElementById('get-binford').addEventListener('click', e => {
execute('', {headers: {'X-Binford': '6100'}});
});
document.getElementById('get-credentials').addEventListener('click', e => {
execute('', {credentials: 'include'});
});
// POST
document.getElementById('post').addEventListener('click', e => {
execute('', {
method: 'POST',
body: 'user=frontend',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
});
});
// PATCH
document.getElementById('patch-binford').addEventListener('click', e => {
execute('', {
method: 'PATCH',
body: 'patch=name',
headers: {'Content-Type': 'application/x-www-form-urlencoded', 'X-Binford': '6100'},
});
});
</script>
</body>
</html>
<?php
use web\Application;
use web\filters\CORS;
class TestAPI extends Application {
const JSON= 'application/json; charset=utf-8';
public function routes() {
$this->install(new CORS()
->origins('http://localhost:3000')
->methods(['GET', 'POST', 'PATCH'])
->headers(['X-Binford']) // Allow X-Binford request header
->expose(['X-Binford']) // Expose X-Binford response header
->credentials(true) // Allow cookies set by JavaScript
);
return [
'HEAD /' => function($req, $res) {
$res->answer(200);
$res->header('X-Binford', $req->header('X-Binford'));
},
'GET /' => function($req, $res) {
$res->answer(200);
$res->header('X-Binford', $req->header('X-Binford'));
$res->send(json_encode(['hello' => $req->param('user') ?? $req->cookie('user') ?? 'World']), self::JSON);
},
'POST /' => function($req, $res) {
$res->answer(200);
$res->header('X-Binford', $req->header('X-Binford'));
$res->send(json_encode(['created' => $req->param('user')]), self::JSON);
},
'PATCH /' => function($req, $res) {
$res->answer(200);
$res->header('X-Binford', $req->header('X-Binford'));
$res->send(json_encode(['patched' => $req->param('patch')]), self::JSON);
},
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment