Fading Coder

One Final Commit for the Last Sprint

Home > Tools > Content

Cross-Domain Data Fetching Using JSONP in JavaScript

Tools 1

Standard XMLHttpRequest-based AJAX cannot retrieve resources from domains not explicitly permitted due to same-origin policy restrictions. JSONP bypasses this limitation by leveraging the ability of certain HTML tags, notably <script>, to load external resources.

A <script> tag fetches its source and executes it as JavaScript code. By requesting a server-side script that returns executable JavaScript, JSONP enables cross-domain data exchange without XHR.

Basic Server Response Example (PHP)

<?php
$username = $_REQUEST['usr'] ?? '';
echo "handleResponse('Greetings {$username}');";
?>

The PHP file above reads a usr parameter and responds with a call to a globally defined function handleResponse, emmbedding the data as a string argument.

Minimal Client Usage Without Encapsulation

<script>
function handleResponse(payload) {
    console.log(payload);
}
</script>
<script src="http://localhost/api/greet.php?usr=admin"></script>

Loading the script triggers execution of handleResponse('Greetings admin').

Dynamic Script Injection Approach

To generalize usage, inject a <script> element at runtime:

<script>
document.addEventListener('click', () => {
    const endpoint = 'http://localhost/api/greet.php';
    performJsonp(endpoint, (result) => {
        console.log(result);
    }, { usr: 'root' });
});

function performJsonp(targetUrl, callbackFn, params) {
    params = params || {};
    let queryString = Object.keys(params).map(k => `${k}=${params[k]}`).join('&');
    const scriptEl = document.createElement('script');
    scriptEl.src = `${targetUrl}?${queryString}`;
    document.body.appendChild(scriptEl);

    window.receiveData = function(data) {
        callbackFn(data);
    };
}
</script>

Server-side must match the invoked global function name (receiveData).

Customizable Callback Parameter Name

Some APIs require specifying the callback name via a query key. Adjust the client to accommodate:

<script>
document.addEventListener('click', () => {
    const endpoint = 'http://localhost/api/custom_cb.php';
    performJsonp(endpoint, (msg) => {
        alert(msg);
    }, {
        pwd: 'root',
        cbField: 'callbackId',
        callbackId: 'arbitraryName'
    });
});

function performJsonp(targetUrl, onSuccess, args) {
    args = args || {};
    const qs = Object.keys(args)
        .filter(key => key !== args.cbField)
        .map(k => `${k}=${args[k]}`)
        .join('&');
    
    const scriptEl = document.createElement('script');
    scriptEl.src = `${targetUrl}?${qs}&${args.cbField}=${args[args.cbField]}`;
    document.body.appendChild(scriptEl);

    window[args[args.cbField]] = function(response) {
        onSuccess(response);
    };
}
</script>

Server-side example matching custom callback key:

<?php
$password = $_REQUEST['pwd'] ?? '';
$cbName   = $_REQUEST['callbackId'] ?? '';
echo "{$cbName}('Welcome {$password}');";
?>

Here, the server extracts both the data parameter (pwd) and the callback identifier (callbackId), then emits a call too the dynamically named function.

Tags: JSONP

Related Articles

Efficient Usage of HTTP Client in IntelliJ IDEA

IntelliJ IDEA incorporates a versatile HTTP client tool, enabling developres to interact with RESTful services and APIs effectively with in the editor. This functionality streamlines workflows, replac...

Installing CocoaPods on macOS Catalina (10.15) Using a User-Managed Ruby

System Ruby on macOS 10.15 frequently fails to build native gems required by CocoaPods (for example, ffi), leading to errors like: ERROR: Failed to build gem native extension checking for ffi.h... no...

Resolve PhpStorm "Interpreter is not specified or invalid" on WAMP (Windows)

Symptom PhpStorm displays: "Interpreter is not specified or invalid. Press ‘Fix’ to edit your project configuration." This occurs when the IDE cannot locate a valid PHP CLI executable or when the debu...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.