JS JSONP
In this page:
Why JSONP Exists
Before CORS, browsers strictly blocked JavaScript from making a cross-origin XMLHttpRequest to a different domain -- but a <script> tag has always been allowed to load a script from any domain, so JSONP exploits that loophole: the "response" is actually loaded as if it were a script file.
Example: Why JSONP Exists
<script src="https://api.example.com/data?callback=handleData"></script>
<script>
// Define the function `handleData` taking `data`
function handleData(data) { console.log(data); }
</script>
How JSONP Works
The client defines a global callback function and requests a URL that includes that function's name as a query parameter -- the server wraps its JSON data in a call to that exact function name, so when the returned "script" loads and executes, it automatically calls your function with the data as an argument.
Example: How JSONP Works
function handleData(data) {
console.log("Received:", data);
}
// Server responds with: handleData({"name": "Sam"});
// which calls handleData automatically once the "script" loads
Dynamically Creating a JSONP Request
Rather than hardcoding a <script> tag in the HTML, JSONP requests are typically triggered dynamically -- creating a new <script> element with JavaScript, setting its src to the target URL, and appending it to the document, which starts the request immediately.
Example: Dynamically Creating a JSONP Request
// Define the function `handleData` taking `data`
// Define the function `handleData` taking `data`
function handleData(data) { console.log(data); }
// Declare the constant `script`, set to `document.createElement("script")`
// Declare the constant `script`, set to `document.createElement("script")`
const script = document.createElement("script");
// Assign "https://api.example.com/data?callback=handleData" to `script.src`
// Assign "https://api.example.com/data?callback=handleData" to `script.src`
script.src = "https://api.example.com/data?callback=handleData";
// Call `document.body.appendChild(script)`
// Call `document.body.appendChild(script)`
document.body.appendChild(script);
JSONP's Limitations
JSONP only supports GET requests, since it relies on loading a URL as a script -- there is no equivalent for sending a POST body.
It also offers no clean way to detect a failed request (no error callback is standard), and it executes the response as real, unrestricted JavaScript in your page.
Example: JSONP's Limitations
// JSONP limitations:
// - only supports GET (loading a URL as a script)
// - no built-in error callback if the request fails
// - executes the response as full, unrestricted JavaScript
console.log("Use CORS with fetch() instead when the API supports it.");
JSONP vs CORS: When to Use Which
For any API you control, or any modern third-party API, CORS is the correct, secure choice -- it lets the server explicitly declare which origins may access it, and works with the full range of HTTP methods and the safer fetch API.
JSONP remains relevant only for old APIs that never added CORS support.
Example: JSONP vs CORS: When to Use Which
fetch("https://api.example.com/data").then(r => r.json()).then(data => console.log(data));
console.log("Prefer CORS/fetch whenever the server supports it.");
- Using JSONP for a new project today when the target API supports CORS -- JSONP has real security downsides and should only be used when CORS is genuinely unavailable.
- Forgetting that JSONP only supports GET requests, since it works by loading a script, and scripts cannot carry a POST body.
- Not recognizing that JSONP executes arbitrary code from the remote server directly in your page's context, which is a meaningful security consideration compared to a same-origin-protected JSON fetch.
- JSONP works by dynamically inserting a <script> tag whose src points to the remote API, sidestepping the same-origin restriction that blocks a plain cross-origin XMLHttpRequest.
- The remote server wraps its JSON data in a call to a callback function name the client specifies, which executes automatically once the script loads.
- JSONP only supports GET requests and executes the remote server's response as actual JavaScript, a real security consideration.
JSONP relies only on basic <script> tag loading, supported in every browser since the earliest days of the web; it predates and is now largely superseded by CORS.
Chapter Quiz — Complete all 26 topics to unlock
0/26 topics done
Complete these topics first:
- JS JSON
- JS Regular Expressions
- JS Fetch API
- JS LocalStorage and SessionStorage
- JS Cookies
- JS setTimeout and setInterval
- JS Event Loop
- JS Web Workers
- JS Service Workers
- JS AJAX
- JS AJAX Intro
- JS AJAX XMLHttp
- JS AJAX Request
- JS AJAX Response
- JS AJAX XML
- JS AJAX PHP
- JS AJAX Database
- JS JSONP
- JS RegExp Flags
- JS RegExp Classes
- JS RegExp Metachars
- JS RegExp Assertions
- JS RegExp Groups
- JS RegExp Quantifiers
- JS JSON HTML
- JS JSON vs XML