JSONP: What It Is, Why It Was Created, and Why CORS Replaced It

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

JSONP: The Secret Weapon of Frontend Developers from the Past

\n

Imagine you're a web developer in 2010. You need to get data from someone else's server, for example, a weather forecast or currency exchange rates. You write a simple fetch request, but a red error appears in the browser console: «No 'Access-Control-Allow-Origin' header is present». Sound familiar?

\n

This is the Same-Origin Policy preventing your JavaScript from accessing anything outside your own domain. But how did weather widgets, «Share» buttons, and visitor counters work back then? The answer is simple: they used JSONP — a clever trick that we'll discuss today.

\n

In this article, we'll answer the popular Stack Overflow question: «What is JSONP, and why was it created?» — in simple terms, with code examples and no unnecessary theory.

\n\n

1. The Problem: Why Does the Browser Block Requests?

\n

The browser is paranoid. It protects the user from XSS attacks and data theft. The Same-Origin Policy only allows JavaScript to read responses from the same domain, protocol, and port.

\n

Example of a blocked request:

\n
// This code will cause a CORS error\nfetch('https://api.distant-server.com/data')\n  .then(response => response.json())\n  .then(data => console.log(data));
\n

But there is one exception: <script> tags. The browser freely loads scripts from any domain! This is exactly the loophole that JSONP exploits.

\n\n

2. The Solution: JSONP — JSON with Padding

\n

JSONP (JSON with Padding) is not a technology or a data format, but a pattern (workaround) that bypasses the Same-Origin Policy using the <script> tag.

\n

The idea is simple: instead of making a request via XMLHttpRequest, we dynamically create a <script> element, point it to the server's URL, and the server returns not JSON, but JavaScript code that calls our function with the data.

\n\n

What regular JSON looks like:

\n
// Server response (regular JSON)\n{"name": "PythonLib", "topic": "JSONP"}
\n\n

What JSONP looks like:

\n
// Server response (JSONP)\nmyCallback({"name": "PythonLib", "topic": "JSONP"});
\n

The difference is huge: in the second case, the server wraps the data in a call to the myCallback function. This is the so-called padding (wrapper).

\n\n

3. Practice: Writing a JSONP Request by Hand

\n

Let's implement a JSONP client in pure JavaScript. This will help you understand the magic.

\n\n
function jsonp(url, callbackName) {\n  // 1. Create a global function (callback)\n  window[callbackName] = function(data) {\n    console.log('Data received:', data);\n    delete window[callbackName]; // Clean up after ourselves\n    document.body.removeChild(script);\n  };\n\n  // 2. Create a script tag\n  const script = document.createElement('script');\n  script.src = `${url}?callback=${callbackName}`; // Pass the callback name\n  script.onerror = function() {\n    console.error('JSONP load error');\n    delete window[callbackName];\n    document.body.removeChild(script);\n  };\n\n  // 3. Add to the DOM — the browser immediately loads and executes the script\n  document.body.appendChild(script);\n}\n\n// Usage:\njsonp('https://api.example.com/data', 'handleData');
\n

How it works step by step:

\n
    \n
  • We create a global function handleData.
  • \n
  • We add a <script> tag with the server's URL. In the URL, we pass the parameter ?callback=handleData.
  • \n
  • The server, supporting JSONP, sees the callback parameter and returns not JSON, but JavaScript: handleData({...}).
  • \n
  • The browser executes this script, our function is called, and we receive the data.
  • \n
\n\n

4. Why is JSONP Evil? (Disadvantages)

\n

If you thought: «Cool, I'll use this everywhere

Blogs

Book Recommendations