33 lines
1.0 KiB
TypeScript
33 lines
1.0 KiB
TypeScript
export type CsrfFetchOptions = RequestInit & { headers?: Record<string, any> };
|
|
|
|
function getMetaToken(): string | null {
|
|
const el = document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement | null;
|
|
return el?.content || null;
|
|
}
|
|
|
|
/**
|
|
* fetch wrapper that automatically adds CSRF and common headers, and sends cookies.
|
|
* - Uses local proxy to avoid Mixed Content (HTTPS -> HTTP) and CORS issues.
|
|
* - Adds X-CSRF-TOKEN from <meta name="csrf-token"> if present
|
|
* - Adds X-Requested-With: XMLHttpRequest for Laravel
|
|
*/
|
|
export async function csrfFetch(input: RequestInfo | URL, options: CsrfFetchOptions = {}): Promise<Response> {
|
|
const token = getMetaToken();
|
|
const headers: Record<string, any> = {
|
|
'X-Requested-With': 'XMLHttpRequest',
|
|
'Accept': 'application/json',
|
|
...(options.headers || {}),
|
|
};
|
|
if (token && !('X-CSRF-TOKEN' in headers)) {
|
|
headers['X-CSRF-TOKEN'] = token;
|
|
}
|
|
|
|
const init: RequestInit = {
|
|
...options,
|
|
headers,
|
|
credentials: options.credentials ?? 'same-origin',
|
|
};
|
|
|
|
return fetch(input, init);
|
|
}
|