$.ajaxPrefilter() is jQuery’s extension point for intercepting every Ajax request before it leaves the browser. This tutorial covers registering global prefilters, the difference between merged options and caller-supplied originalOptions, scoping handlers with a dataTypes filter, modifying settings (headers, cache, custom flags), the official abortOnRetry pattern, returning a dataType string to redirect processing, and how prefilters fit between $.ajaxSetup() and beforeSend.
01
Prefilter hook
Global interceptor
02
options / originalOptions
Merged vs raw
03
dataTypes filter
Scoped handlers
04
Modify settings
Headers, cache, URL
05
Abort pattern
Duplicate URL guard
06
Since 1.5
Core Ajax API
Fundamentals
Introduction
When your app grows beyond a handful of $.ajax() calls, you often need the same cross-cutting behavior everywhere: attach an auth token, bust GET caches during development, abort stale autocomplete requests, or log traffic for debugging. Copy-pasting that logic into every call is brittle. jQuery solves this with jQuery.ajaxPrefilter() — a registration API that runs a handler before each Ajax request is processed and sent.
Prefilters sit in the pipeline after $.ajaxSetup() defaults are merged but before the per-request beforeSend callback and the actual network transport. That timing matters: you can rewrite URLs, inject headers, wrap beforeSend, store the returned jqXHR for later abort, or even return a dataType string to tell jQuery to treat the request differently. Every shorthand — $.get(), $.post(), .load() — flows through the same prefilter chain.
Concept
Understanding jQuery.ajaxPrefilter()
jQuery.ajaxPrefilter() does not send a request itself. It registers a function jQuery invokes for qualifying Ajax calls. Inside the handler you receive three arguments: the merged options object (what jQuery will use), the unmodified originalOptions from the caller, and the jqXHR object for this request. Mutate options to change behavior; inspect originalOptions when you need to know what the caller explicitly passed versus what came from global defaults.
Register prefilters once — typically when your application bootstraps — not inside every click handler. Multiple prefilters stack in registration order. Optional custom properties (like the documented abortOnRetry example) can live on the options object; your prefilter reads them and acts accordingly. Returning a string such as "script" or "json" from the handler redirects the request to that dataType and triggers any dataType-specific prefilters registered for it.
💡
Beginner Tip
Reach for $.ajaxSetup() when you only need static defaults (base URL, common headers). Reach for $.ajaxPrefilter() when logic must inspect or transform each request dynamically — abort duplicates, rewrite cross-domain URLs, or branch on custom flags the caller sets per request.
Foundation
📝 Syntax
The official jQuery API accepts two signatures:
1. Global prefilter — jQuery.ajaxPrefilter( handler )
jQuery
jQuery.ajaxPrefilter( handler )
Runs the handler before every Ajax request (all dataTypes).
Three hooks at different stages — pick the right layer for defaults, global logic, or per-request control.
ajaxPrefilter
global hook
Runs for every request (or matching dataTypes) — modify merged options, store jqXHR, return dataType string; runs before beforeSend
$.ajaxSetup()
static defaults
Sets default option values merged into future requests — url prefix, headers object, global:false; no per-request logic unless combined with a prefilter
beforeSend
per-request
Settings callback on one call — set headers on jqXHR, return false to cancel; runs after all prefilters, just before transport sends
Combined pattern
setup + prefilter
Use ajaxSetup for base URL, ajaxPrefilter for dynamic auth and abort logic, beforeSend only when one call needs unique behavior
Use $.ajaxPrefilter() when the same conditional logic must run across the entire app. Use $.ajaxSetup() for values that rarely change. Use beforeSend in individual $.ajax() calls when only that request needs special handling — or set it inside a prefilter when every request needs the same header logic.
Hands-On
Examples Gallery
Five progressive examples from a basic log-and-modify prefilter through the official abort-on-retry pattern, JSON-scoped prefilters, forced GET cache busting, and global Authorization headers. Each links to a Try-it lab where you can edit and run the code in the browser.
📚 Core Patterns
Register prefilters once at startup and let every Ajax call inherit the behavior.
Example 1 — Basic Registration — Log and Modify Before Every Request
Register a global prefilter that logs the URL and ensures every request sends a custom header identifying your app.
Page loads → prefilter registered once
Click #load → console logs "Ajax prefilter: https://jsonplaceholder..."
Request includes X-App-Client header → .done() shows post title
How It Works
The prefilter runs before the transport sends the request. Mutating options.headers applies to this call only — jQuery merges headers when building the XHR. originalOptions still reflects what the click handler passed; use it if you need to detect whether the caller set headers explicitly.
Example 2 — Official abortOnRetry Pattern — Abort Duplicate URL Requests
Adapted from the jQuery API docs: when a custom abortOnRetry flag is set, abort any in-flight request to the same URL before starting a new one.
User types quickly in #search
Each keystroke starts $.ajax with abortOnRetry: true
Prefilter aborts previous jqXHR to same URL → only latest .done() updates #count
How It Works
Custom options like abortOnRetry are ignored by jQuery’s transport — they exist for your prefilter. Storing jqXHR by URL lets you call .abort() on stale autocomplete or search requests. Only calls that opt in with the flag are affected; other Ajax traffic is untouched.
Example 3 — dataTypes: "json" Scoped Prefilter
Apply logging and a JSON-specific header only when the request expects a JSON response — HTML or script requests skip this handler.
Click #load-user → "JSON prefilter:" logged → user name shown
Click #load-html → JSON prefilter does NOT run → different message in #name
How It Works
The first argument filters by dataType. Pass multiple types as a space-separated string — "json script" matches either. This keeps JSON API instrumentation separate from page fragment loads or script injection without branching on options.dataType inside a global handler.
📈 Defaults & Headers
Enforce cache policy and authentication across the entire Ajax layer.
Example 4 — Force cache: false on All GET Requests
During development, bust browser caches for every GET without adding cache: false to each call.
Each click on #refresh → fresh GET with _=timestamp query param
Prefilter sets cache: false → browser does not serve stale cached JSON
#log timestamp updates every click
How It Works
jQuery appends a cache-busting _=timestamp parameter when cache: false on GET. The prefilter respects explicit cache: true if a caller opts in. Remove or gate this prefilter in production if your CDN relies on GET caching.
Example 5 — Add Authorization Header via Prefilter beforeSend
Attach a bearer token to every API request by wrapping or setting options.beforeSend inside the prefilter — runs before the per-request callback chain.
Click #fetch → prefilter wraps beforeSend
Authorization: Bearer demo-token-abc123 sent on the wire
Public API ignores token but request succeeds → #status shows email
How It Works
Prefilters run before beforeSend is invoked. Saving and chaining the previous beforeSend preserves per-request hooks callers already set. Alternatively set options.headers directly — both approaches work; beforeSend is useful when you need the raw XHR object or must return false to cancel.
Applications
🚀 Common Use Cases
Global auth headers — attach API tokens or session cookies via prefilter instead of repeating beforeSend on every call.
Abort stale requests — autocomplete, typeahead, and fast-click scenarios — store jqXHR by URL or key and abort on retry.
Development cache busting — force cache: false on GET during local testing without touching each endpoint call.
Cross-domain proxy rewrite — detect crossDomain and rewrite options.url through your server proxy (official jQuery doc pattern).
JSON-only instrumentation — register $.ajaxPrefilter("json", ...) to log or transform API traffic separately from HTML loads.
Custom option flags — define app-specific properties (abortOnRetry, retryCount) read only by your prefilters.
dataType redirection — return "script" from a prefilter when URL patterns imply script execution instead of HTML.
🧠 ajaxPrefilter in the Ajax Pipeline
1
Caller invokes $.ajax()
Settings passed to $.ajax(), $.get(), or $.post() — stored as originalOptions.
$.ajax( settings )
2
$.ajaxSetup() merge
Global defaults from $.ajaxSetup() merge into settings — result becomes mutable options.
ajaxSetup defaults
3
ajaxPrefilter handlers
Registered prefilters run in order — modify options, store jqXHR, or return a dataType string.
ajaxPrefilter
4
beforeSend
Per-request beforeSend runs — set headers on jqXHR or return false to cancel.
beforeSend
5
Transport sends
XHR (or chosen transport) sends bytes — global ajaxSend fires if global: true.
ajaxSend → network
6
👉
Response callbacks & global events
Success or error handlers, jqXHR .done() / .fail(), then ajaxSuccess, ajaxError, ajaxComplete, and ajaxStop.
Important
📝 Notes
$.ajaxPrefilter() was added in jQuery 1.5 alongside Deferred-backed jqXHR — the same release that introduced .done() / .fail().
Register prefilters once at application startup — not inside event handlers that fire repeatedly.
options includes merged defaults; originalOptions is what the caller passed before merge.
Returning a dataType string from a handler redirects processing and runs dataType-specific prefilters for that type.
Custom properties on the options object (e.g. abortOnRetry) are for your code — jQuery ignores unknown keys.
Prefilters run before beforeSend — ideal for wrapping or replacing beforeSend globally.
Scoped prefilters use a space-separated dataTypes string: "json script" matches either type.
There is no built-in $.ajaxUnprefilter() — avoid registering duplicate handlers on SPA re-init.
Compatibility
Browser Support
jQuery.ajaxPrefilter() is part of jQuery’s core Ajax module — not a native DOM API. It works wherever jQuery’s Ajax transport runs: all browsers supported by your jQuery version, including legacy IE with supported jQuery builds.
✓ jQuery 1.5+
jQuery.ajaxPrefilter() method
Supported in jQuery 1.x, 2.x, and 3.x across all modern browsers and IE with supported jQuery builds. ajaxPrefilter arrived in jQuery 1.5 together with the Deferred-based jqXHR pipeline. Prefilters apply to all Ajax transports jQuery selects for the request.
100%With jQuery
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
$.ajaxPrefilter()Universal
Bottom line: Safe in any jQuery 1.5+ project. Pair prefilters with $.ajaxSetup() for static defaults and beforeSend for one-off per-request tweaks. Prefilters do not replace global Ajax events — ajaxStart still fires after the transport pipeline begins.
Wrap Up
Conclusion
jQuery.ajaxPrefilter() is the right tool when every Ajax call needs shared, conditional logic — auth headers, cache policy, abort-on-retry, URL rewriting, or dataType redirection. Register handlers once, mutate merged options, inspect pristine originalOptions, and optionally scope with a dataTypes filter or return a dataType string to redirect processing.
Prefilters run after $.ajaxSetup() merge and before beforeSend and the network transport. Continue with the ajaxSetup() tutorial to understand global default options (and why jQuery recommends against them), then explore ajaxStart for page-wide loading indicators.
Chain existing beforeSend when wrapping it inside a prefilter
Use dataTypes scoping for JSON-only or script-only logic
Store jqXHR references when implementing abort-on-retry patterns
Compare originalOptions when you need caller intent vs merged defaults
❌ Don’t
Register the same prefilter repeatedly on route changes without guarding
Put heavy synchronous work in prefilters — they block every Ajax call
Assume custom option keys affect jQuery — only your prefilter reads them
Force cache: false on all GET in production without a deliberate reason
Embed secrets in client-side token variables — use secure session patterns server-side
Summary
Key Takeaways
Knowledge Unlocked
Six things to remember about $.ajaxPrefilter()
Register once, mutate options, run early.
6
Core concepts
hook01
Prefilter hook
Global interceptor
Foundation
opt02
options vs orig
Merged vs raw
Inspect
type03
dataTypes
Scoped filter
json
edit04
Modify settings
Headers, cache
Mutate
abort05
Abort pattern
Store jqXHR
Retry
1506
Since 1.5
Core Ajax API
Stable
❓ Frequently Asked Questions
jQuery.ajaxPrefilter() registers a handler that runs before each Ajax request is sent and before jQuery finishes processing the settings object. Use it to set defaults, modify options globally, attach custom logic like abort-on-retry, or redirect a request to another dataType. Every $.ajax(), $.get(), $.post(), and .load() call passes through registered prefilters.
Prefilters run early — after $.ajaxSetup() defaults are merged into the per-request settings, but before the transport sends bytes and before the per-request beforeSend callback. Multiple prefilters run in registration order. This makes ajaxPrefilter ideal for cross-cutting changes that must apply before beforeSend and global ajaxSend events.
options is the merged settings object jQuery will use for the request — it includes defaults from $.ajaxSetup() and jQuery.ajaxSettings. originalOptions is exactly what you passed to $.ajax() (or what a shorthand like $.get() built internally), without those merged defaults. Compare them when you need to know whether a value came from the caller or from global setup.
When you call $.ajaxPrefilter("json script", handler), the handler runs only for requests whose dataType matches one of the space-separated types — for example dataType: "json" or a JSON response inferred for script requests. Omit dataTypes to run the handler on every Ajax request regardless of dataType.
If your prefilter handler returns a string such as "script" or "json", jQuery treats the request as that dataType. That affects transport selection and runs any prefilters registered specifically for that dataType. Use this when URL patterns or custom flags imply a different response type than the caller specified.
$.ajaxSetup() sets default option values merged into every future request — static defaults like url or headers. beforeSend runs once per individual request just before send, with jqXHR access, and can return false to cancel. ajaxPrefilter runs for every request (or matching dataTypes), receives both merged options and pristine originalOptions, can modify options before beforeSend is invoked, and can return a dataType string to redirect processing.
Did you know?
jQuery’s official documentation uses $.ajaxPrefilter() for the abortOnRetry pattern — a custom option that only your prefilter understands. jQuery 1.5 introduced prefilters alongside the Deferred-based jqXHR rewrite, giving you a hook that runs after $.ajaxSetup() defaults merge but before beforeSend. Returning "script" from a prefilter not only changes transport behavior but also ensures script-specific prefilters registered with $.ajaxPrefilter("script", ...) run for that request.