Question

What Is JSONP in JavaScript? Why It Was Created and How It Works

javascriptjsonjsonpterminology

Question

I understand JSON as a data format, but I do not understand JSONP.

One definition says:

JSONP or "JSON with padding" is a JSON extension wherein a prefix is specified as an input argument of the call itself.

That is confusing to me because JSON is just a data format. There is no obvious "call" involved.

Another explanation says:

JSONP is script tag injection, passing the response from the server into a user-specified function.

I partly understand that, but I still do not see the full picture.

So what exactly is JSONP? Why was it created, what problem was it trying to solve, and why would someone use it?

For example, what is happening in a pattern like this?

function handleData(data) {
  console.log(data);
}

const script = document.createElement('script');
script.src = 'https://example.com/data?callback=handleData';
document.body.appendChild(script);

Short Answer

By the end of this page, you will understand that JSONP is not a new data format, but a technique for loading data by wrapping JSON inside a JavaScript function call. It was created to work around older browser same-origin restrictions that blocked normal AJAX requests to other domains. You will learn how JSONP works, why it existed, its limitations, its security risks, and why modern applications usually use CORS instead.

Concept

JSONP stands for JSON with Padding.

The most important idea is this:

  • JSON is plain data.
  • JSONP is JavaScript code that calls a function and passes JSON data into it.

A normal JSON response looks like this:

{"name":"Alice","age":30}

A JSONP response looks like this:

handleData({"name":"Alice","age":30});

The handleData(...) part is the padding. The JSON data is wrapped in a function call.

Why JSONP was created

Older browsers enforced the same-origin policy for AJAX requests. That meant JavaScript on one website could not easily fetch data from another domain using XMLHttpRequest.

For example:

  • A page on https://myapp.com could not make a normal AJAX request to https://api.example.com.

However, browsers did allow loading JavaScript files from other domains using a <script> tag:

<script src="https://api.example.com/file.js"></script>

This was allowed because websites often needed external scripts.

Developers realized they could use that permission to fetch data disguised as JavaScript.

Instead of returning raw JSON, the server returned JavaScript that called a function already defined on the page.

Example:

showUser({"id":1,"name":"Alice"});

When the browser loaded that script, it executed immediately and passed the data into showUser.

That workaround is JSONP.

What problem JSONP solved

JSONP solved this old problem:

  • "I need data from another domain, but the browser blocks my AJAX request."

JSONP let developers retrieve data across domains without server-side proxies and before CORS became standard.

Why the word "call" is used

The confusing definition mentions a "call" because JSONP is based on a function call.

The browser requests a URL like this:

https://example.com/data?callback=handleData

The server reads the callback=handleData part and sends back:

handleData({"message":"Hello"});

That response is JavaScript code. When loaded through a <script> tag, the browser executes it.

So the "call" is the server-generated function call in the response.

Why JSONP matters historically

JSONP was very important before CORS.

It helped developers:

  • load public API data from another domain
  • build mashups using multiple services
  • avoid building their own server-side relay just to fetch external data

Today, JSONP is mostly a legacy technique because CORS is safer and more flexible.

Mental Model

Imagine your web page is a house.

  • JSON is like a sealed package left at the door. It contains data.
  • AJAX is like sending someone through the front gate to pick up the package.
  • The same-origin policy is a guard that says, "You cannot fetch packages from that other neighborhood."

But there is one exception:

  • The guard allows newspapers from other neighborhoods to be delivered through the mail slot.
  • A <script> tag is that mail slot.

So instead of sending just a package of data, the other server sends a newspaper article that says:

handleData({"name":"Alice"});

Your page has already prepared a function named handleData, so when the script arrives, the browser reads it out loud and your function receives the data.

That is JSONP: using the browser's ability to load external scripts as a way to receive cross-domain data.

Take Quiz

Syntax and Examples

Core pattern

Client-side code:

function handleData(data) {
  console.log('Received:', data);
}

const script = document.createElement('script');
script.src = 'https://api.example.com/user?callback=handleData';
document.body.appendChild(script);

Possible server response:

handleData({"id":1,"name":"Alice"});

What each part does

  • The page defines a global function such as handleData.
  • The page creates a <script> element.
  • The src points to another domain.
  • The URL includes a callback name.
  • The server returns JavaScript that calls that function.
  • The browser loads and executes that script.

Beginner-friendly example

Suppose you want weather data from another domain.

Page code

function showWeather(data) {
  console.log(`City: ${data.city}`);
  console.log(`Temperature: ${data.temperature}`);
}

const script = document.createElement('script');
script.src = 'https://weather.example.com/current?callback=showWeather';
document.body.appendChild(script);

Server response

showWeather({"city":"London","temperature":18});

Result

When the script loads, the browser executes:

showWeather({"city":"London","temperature":18});

So your showWeather function receives the data object.

Why this is not plain JSON

This is JSON:

{"city":"London","temperature":18}

This is JSONP:

showWeather({"city":"London","temperature":18});

JSONP is executable JavaScript, not just data.

Step by Step Execution

Consider this code:

function handleData(data) {
  console.log('Name:', data.name);
}

const script = document.createElement('script');
script.src = 'https://example.com/user?callback=handleData';
document.body.appendChild(script);

Assume the server responds with:

handleData({"name":"Alice"});

Step-by-step

1. Define the callback function

function handleData(data) {
  console.log('Name:', data.name);
}

The page creates a function named handleData. This function will receive data later.

2. Create a script element

const script = document.createElement('script');

This creates a new <script> tag in memory.

3. Set the source URL

script.src = 'https://example.com/user?callback=handleData';

The browser is told to load a script from another domain.

The URL includes callback=handleData, which tells the server which function name to use.

4. Add the script to the page

document.body.appendChild(script);

As soon as the script is added to the document, the browser requests the URL.

5. Server builds the response

The server sees callback=handleData and returns:

handleData({"name":"Alice"});

6. Browser executes the script

Because it came through a <script> tag, the browser treats the response as JavaScript code.

7. Your function runs

handleData({"name":"Alice"});

This calls your function with the object.

8. Output appears

Name: Alice

Key observation

The browser never parsed a JSON response from AJAX here. It simply loaded and executed JavaScript from another server.

Real World Use Cases

Historical use cases

JSONP was commonly used for:

  • Public APIs that needed to support browser access from any site
  • Widgets embedded on third-party websites
  • Mashups that combined data from several services on one page
  • Search suggestions and autocomplete from external services
  • Analytics or ad scripts that returned dynamic data

Example scenarios

1. Public API consumption

A news site might fetch headlines from another domain using JSONP.

2. Embeddable widgets

A stock ticker widget embedded on many websites could request live data from the provider's domain.

3. Third-party integrations

A page could show social media counts or public profile information from another service.

Where it is less suitable

JSONP was never ideal for:

  • private data
  • authenticated requests
  • non-GET operations
  • reliable error handling

That is one reason modern apps prefer fetch with CORS.

Take Quiz

Real Codebase Usage

In real projects, JSONP usually appeared as a fallback or as a feature for older APIs.

Common patterns

1. Callback parameter convention

Servers often accepted query parameters like:

  • callback=myFunction
  • jsonp=myFunction
  • cb=myFunction

The backend inserted that function name into the response.

2. Dynamically generated callback names

To avoid naming collisions, developers often generated unique global functions:

const callbackName = 'jsonpCallback_' + Date.now();

window[callbackName] = function (data) {
  console.log(data);
  delete window[callbackName];
};

3. Cleanup after execution

After the callback ran, code often removed:

  • the global callback function
  • the injected <script> element

This prevented memory leaks and duplicate calls.

4. Guard clauses

Developers often checked that the response had expected fields before using it:

window[callbackName] = function (data) {
  if (!data || !data.name) {
    console.error('Invalid response');
    return;
  }

  console.log(data.name);
};

5. Timeout handling

Because JSONP has weak error reporting, code often used timeouts:

const timeoutId = setTimeout(() => {
  console.error('Request timed out');
}, 5000);

Then the callback cleared the timeout when data arrived.

Important limitation in real code

JSONP only works when the server explicitly supports it. A client cannot force an ordinary JSON endpoint to behave like JSONP.

Common Mistakes

1. Thinking JSONP is a data format

JSONP is not a replacement for JSON.

  • JSON = data
  • JSONP = JavaScript function call containing data

Broken assumption:

// Wrong idea: treating JSONP as plain JSON
const data = '{"name":"Alice"}';

Actual JSONP response:

handleData({"name":"Alice"});

2. Forgetting that the callback must exist globally

Because the response executes as script, the callback usually needs to be accessible on window.

Broken example:

(function () {
  function handleData(data) {
    console.log(data);
  }
})();

If the server calls handleData(...), it may fail because handleData is not global.

Safer version:

window.handleData = function (data) {
  console.log(data);
};

3. Assuming JSONP supports POST, PUT, or DELETE

JSONP works through a <script> URL request, so it is effectively limited to GET.

4. Ignoring security risks

A JSONP response is executable JavaScript from another domain.

That means you are not just accepting data — you are running code.

If the server is compromised or untrusted, that is dangerous.

5. Expecting good error handling

With fetch, you can inspect status codes more clearly. With JSONP, error handling is awkward and inconsistent.

6. Not cleaning up callbacks

If you create many JSONP requests and never remove the callback functions or script tags, your page can become messy.

7. Using JSONP when CORS is available

Modern APIs should usually use:

fetch('https://api.example.com/data')

with proper CORS headers on the server, instead of JSONP.

Comparisons

JSON vs JSONP

FeatureJSONJSONP
TypeData formatJavaScript technique
Example{"name":"Alice"}handleData({"name":"Alice"});
ExecutableNoYes
Cross-domain workaroundNoYes, historically
Security riskLowerHigher, because it executes script

JSONP vs AJAX with CORS

FeatureJSONPAJAX/fetch with CORS
Transport style<script> tagXMLHttpRequest or fetch
Supported methodsMostly GET onlyGET, POST, PUT, DELETE, etc.
Response typeJavaScript codeData such as JSON
Error handlingLimitedBetter
Security modelExecutes third-party scriptControlled by CORS headers
Modern usageLegacyStandard

JSONP vs server-side proxy

ApproachHow it worksWhen used
JSONPBrowser loads cross-domain scriptLegacy public endpoints
Server-side proxyYour server fetches remote data and forwards itWhen you need control, auth, or safer integration

When to choose what

  • Use JSON for data representation.
  • Use CORS for modern cross-origin browser requests.
  • Use JSONP only when working with an old API that already supports it.
Take Quiz

Cheat Sheet

Quick definition

  • JSON: plain data format
  • JSONP: JavaScript function call containing JSON data
  • Purpose: old workaround for cross-domain browser restrictions

JSON example

{"name":"Alice"}

JSONP example

handleData({"name":"Alice"});

Basic flow

  1. Define a global callback function
  2. Create a <script> tag
  3. Set src to a URL with a callback parameter
  4. Server returns JavaScript that calls your function
  5. Browser executes it

Typical client code

window.handleData = function (data) {
  console.log(data);
};

const script = document.createElement('script');
script.src = 'https://example.com/api?callback=handleData';
document.body.appendChild(script);

Typical server response

handleData({"ok":true});

Key rules

  • JSONP is not plain JSON
  • JSONP requires server support
  • JSONP usually works only with GET
  • JSONP runs remote JavaScript
  • JSONP is mostly replaced by CORS

Main drawbacks

  • security risk
  • poor error handling
  • no clean support for most HTTP methods
  • requires global callback naming

Modern alternative

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data));

Use this with proper CORS headers on the server.

FAQ

Is JSONP the same as JSON?

No. JSON is a data format. JSONP is a technique where JSON data is wrapped inside a JavaScript function call.

Why was JSONP needed?

It was used to bypass old browser same-origin restrictions that blocked cross-domain AJAX requests.

Does JSONP still matter today?

Mostly for legacy systems. Modern applications usually use fetch or XMLHttpRequest with CORS.

Is JSONP safe?

It is less safe than plain JSON because it executes JavaScript from another domain. Only use it with trusted sources.

Can JSONP send POST requests?

No, not in the normal way. JSONP works through a <script> request, which is effectively GET-only.

Can any API be used with JSONP?

No. The server must explicitly support JSONP and return a callback-wrapped response.

What does "padding" mean in JSONP?

It means the JSON data is padded or wrapped with extra text: a function name and parentheses.

What replaced JSONP?

CORS became the standard solution for cross-origin browser requests.

Take Quiz

Mini Project

Description

Build a small JSONP loader utility to understand how cross-domain script-based data loading works. This project demonstrates the full JSONP pattern: creating a callback, injecting a script tag, receiving data, handling timeouts, and cleaning up after the request.

Goal

Create a reusable jsonpRequest function that loads JSONP data from a URL and resolves it in a callback-based style.

Requirements

  • Create a function that accepts a URL and a callback parameter name.
  • Generate a unique global callback function name for each request.
  • Inject a <script> tag with the callback name added to the URL.
  • Call a success handler when data arrives.
  • Clean up the script element and callback function after completion.
  • Add timeout handling for requests that never respond.
Take Quiz

Keep learning

Related questions

View more