jQuery ajaxPrefilter() Method

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Core Ajax API

What You’ll Learn

$.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

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.

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.

📝 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).

2. dataTypes-scoped — jQuery.ajaxPrefilter( dataTypes, handler )

jQuery
jQuery.ajaxPrefilter( dataTypes, handler )

dataTypes is a space-separated string such as "json" or "json script". The handler runs only when the request matches one of those types.

Handler arguments

  • options — merged settings jQuery will use (includes $.ajaxSetup() defaults).
  • originalOptions — the object passed to $.ajax() before defaults were applied.
  • jqXHR — the jqXHR object for this request; store it to call .abort() later.

3. Official demo — typical registration

jQuery
$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
  // Modify options, inspect originalOptions, store jqXHR, etc.
  console.log( "Prefilter:", options.url );
} );

Return value

  • $.ajaxPrefilter() returns undefined — it only registers handlers.
  • Return a dataType string (e.g. "script") from the handler to redirect the request to that type.
  • Mutating options affects the current request; registration is permanent until page unload.
  • Prefilters run for shorthands too — $.get() and $.post() internally call $.ajax().

⚡ Quick Reference

GoalCode
Register global prefilter$.ajaxPrefilter(function(o, orig, xhr) { ... })
JSON-only prefilter$.ajaxPrefilter("json", function(o) { ... })
Log every request URLoptions.url inside the handler
Compare caller vs defaultsoriginalOptions vs merged options
Abort duplicate URLStore jqXHR by URL; call .abort() on retry
Force GET cache offif (options.type === "GET") options.cache = false
Add auth header globallyoptions.beforeSend = function(xhr) { xhr.setRequestHeader(...) }
Redirect dataTypereturn "script" from handler when URL matches
Custom per-request flagPass abortOnRetry: true; read it in prefilter

📋 ajaxPrefilter vs $.ajaxSetup() vs beforeSend

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.

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.

jQuery
$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
  console.log( "Ajax prefilter:", options.url );

  // Merged options — safe to mutate for this request
  options.headers = $.extend( {}, options.headers, {
    "X-App-Client": "CodeToFun-Demo"
  } );
} );

$( "#load" ).on( "click", function() {
  $.ajax( {
    url: "https://jsonplaceholder.typicode.com/posts/1",
    dataType: "json"
  } ).done( function( data ) {
    $( "#result" ).text( "Loaded: " + data.title );
  } );
} );
Try It Yourself

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.

jQuery
var currentRequests = {};

$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
  if ( options.abortOnRetry ) {
    if ( currentRequests[ options.url ] ) {
      currentRequests[ options.url ].abort();
    }
    currentRequests[ options.url ] = jqXHR;
  }
} );

$( "#search" ).on( "input", function() {
  var q = $( this ).val();
  $.ajax( {
    url: "https://jsonplaceholder.typicode.com/posts?q=" + encodeURIComponent( q ),
    abortOnRetry: true,
    dataType: "json"
  } ).done( function( posts ) {
    $( "#count" ).text( posts.length + " results" );
  } );
} );
Try It Yourself

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.

jQuery
$.ajaxPrefilter( "json", function( options, originalOptions, jqXHR ) {
  console.log( "JSON prefilter:", options.url );
  options.headers = $.extend( {}, options.headers, {
    "Accept": "application/json"
  } );
} );

$( "#load-user" ).on( "click", function() {
  $.ajax( {
    url: "https://jsonplaceholder.typicode.com/users/1",
    dataType: "json"
  } ).done( function( user ) {
    $( "#name" ).text( user.name );
  } );
} );

$( "#load-html" ).on( "click", function() {
  $.ajax( {
    url: "https://jsonplaceholder.typicode.com/posts/1",
    dataType: "html"
  } ).done( function() {
    $( "#name" ).text( "HTML request — JSON prefilter skipped" );
  } );
} );
Try It Yourself

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.

jQuery
$.ajaxPrefilter( function( options ) {
  var method = ( options.type || options.method || "GET" ).toUpperCase();

  if ( method === "GET" && options.cache !== true ) {
    options.cache = false;
  }
} );

$( "#refresh" ).on( "click", function() {
  $.ajax( {
    url: "https://jsonplaceholder.typicode.com/posts/1"
  } ).done( function( post ) {
    $( "#log" ).text( "Fetched at " + new Date().toLocaleTimeString() + " — " + post.title );
  } );
} );
Try It Yourself

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.

jQuery
var apiToken = "demo-token-abc123";

$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
  var previousBeforeSend = options.beforeSend;

  options.beforeSend = function( xhr, settings ) {
    xhr.setRequestHeader( "Authorization", "Bearer " + apiToken );

    if ( $.isFunction( previousBeforeSend ) ) {
      return previousBeforeSend.call( this, xhr, settings );
    }
  };
} );

$( "#fetch" ).on( "click", function() {
  $.ajax( {
    url: "https://jsonplaceholder.typicode.com/users/1",
    dataType: "json"
  } ).done( function( user ) {
    $( "#status" ).text( "Authorized fetch OK: " + user.email );
  } );
} );
Try It Yourself

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.

🚀 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.

📝 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.

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 Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All 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.

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.

💡 Best Practices

✅ Do

  • Register prefilters once when the app initializes
  • 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

Key Takeaways

Knowledge Unlocked

Six things to remember about $.ajaxPrefilter()

Register once, mutate options, run early.

6
Core concepts
opt 02

options vs orig

Merged vs raw

Inspect
type 03

dataTypes

Scoped filter

json
edit 04

Modify settings

Headers, cache

Mutate
abort 05

Abort pattern

Store jqXHR

Retry
15 06

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.

Next: ajaxSetup() Method

Learn how global Ajax defaults merge into every request — and why jQuery recommends explicit options or a wrapper instead.

ajaxSetup() tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful