Any non-2xx response rejects with an Error that carries .status and the parsed body as .data. A timeout option aborts the underlying fetch through an AbortController, and the rejection's name is 'AbortError'. Call .abort() on the returned promise to cancel yourself — useful when a newer search makes an older one irrelevant.
The flaky endpoint below fails about 60% of the time at random, on the server, so the retry demo is honest: sometimes it succeeds first try, sometimes it needs three.
Pick a failure.
View the source for this demo
<div class="row">
<button type="button" id="te-404">GET a 404</button>
<button type="button" id="te-500">GET a 500</button>
<button type="button" id="te-timeout">Timeout 800 ms vs 3 s server</button>
<button type="button" id="te-abort">Abort after 400 ms</button>
<button type="button" id="te-retry">Retry with backoff</button>
</div>
<pre class="out" id="te-out" aria-live="polite">Pick a failure.</pre>const out = msg => $('#te-out').text(msg);
$('#te-404').on('click', () =>
$.ajax('/api/fail.php?code=404').fail(err => out('.fail() → status ' + err.status + ': ' + err.data)));
$('#te-500').on('click', async () => {
try { await $.get('/api/fail.php?code=500'); }
catch (err) { out('try/catch → status ' + err.status); }
});
$('#te-timeout').on('click', () => {
out('Waiting up to 800 ms…');
$.ajax({ url: '/api/slow.php?ms=3000', timeout: 800 })
.fail(err => out(err.name + ' — gave up after 800 ms; the server needed 3 s.'));
});
$('#te-abort').on('click', () => {
out('Started; aborting in 400 ms…');
const req = $.ajax('/api/slow.php?ms=3000');
req.fail(err => out('.abort() → ' + err.name));
setTimeout(() => req.abort(), 400);
});
async function withRetry(url, tries = 4) {
for (let i = 1; i <= tries; i++) {
try { return { data: await $.get(url), attempt: i }; }
catch (err) {
out('Attempt ' + i + ' → ' + err.status + (i < tries ? ', retrying in ' + 200 * 2 ** i + ' ms…' : ''));
if (i === tries) throw err;
await new Promise(r => setTimeout(r, 200 * 2 ** i));
}
}
}
$('#te-retry').on('click', async () => {
try {
const { data, attempt } = await withRetry('/api/flaky.php');
out('Succeeded on attempt ' + attempt + ': ' + data);
} catch (err) { out('Gave up after 4 attempts.'); }
});More examples
Cancel stale searches
let pending;
$('#q').on('input', $.debounce(async function () {
pending?.abort(); // cancel the previous request
pending = $.get('/api/search', { q: this.value });
try { $('#results').html(await pending); } catch (e) { /* aborted or failed */ }
}, 200));API
Full-control requests. Options: url, method (or jQuery’s type), data (object → urlencoded or querystring; FormData; string), json: true (send JSON body), dataType (’json’ | ’auto’), headers, timeout (ms, auto-aborts), credentials, and callbacks success(data, status, res), error(err), complete(). The promise also has .abort().
Related features
AJAX with $.ajax
jQuery's $.ajax rebuilt on fetch: native Promises and async/await, JSON bodies, headers, timeouts with auto-abort, plus success/error callbacks and .done/.fail for migration..
Open →HyperRequest lifecycle events
Every declarative request emits bubbling lifecycle events — kj:before, kj:after, kj:error and kj:load — so one document-level listener can drive a page-wide progress bar or error toast..
Open →UtilitiesDebounce & throttle
See the difference between debounce and throttle in real time: raw, throttled and debounced event lanes driven by your pointer.
Open →