I’ve already written about How to use JSONP in WordPress Development. I explain how it works, and why you would use it there.
At work we work with several domains and I’ve had to use quite a bit of JSONP, I’ve rethought how to use it, and made this micro-framework to make it a LOT easier. Mostly, I wrote this to solve the problem that I’m using a lot of AJAX, and don’t want the overhead of the .ajax call each time.
There are a lot of values you need to set when making a JSONP call in general, and specifically with WordPress, this greases those wheels.
The paradigm is all you do is execute:
wp_jsonp("wp_jsonp", "getStuff", {variable: "hello world"}, getStuff);
and the rest is taken care of on the JS side. I wrote it to be agnostic of the server-side processing as well, this gives you the benefit of a pseudo factory design pattern with your switch statement.
You can download the whole repo to peruse or play with if you like, I made some gists for easy embedding.
This is the guts of the operation, I created this javascript object that handles everything, you past the ajax event, method, parameters and a callback function. The plugin takes care of the nitty gritty details that are a pain to remember for getting jsonp to work.
It’s well commented, so read through and feel free to ask questions in the comments if you have any.
if (typeof wp_jsonp === 'undefined')
var wp_jsonp = function (event, method, params, callbackFunc) {
// data needed to send jsonp
var data = {
action: event, // wp ajax action
ajaxSSLNonce: wp_jsonp_vars.wpAJAXNonce, // nonce
method: method, // server has switch/case for processing
params: params // data to be processed
};
jQuery.ajax({
type: "GET", // this is the essence of jsonp
url: wp_jsonp_vars.ajaxurl, // wp ajax url
cache: false, // to ensure proper data response
dataType: "jsonp", // jsonp
crossDomain: true, // enable ssl/nonssl
data: data, // data to be sent
success: function (response) {
//console.log('success', response);
// your callback function
callbackFunc(response);
},
complete: function (response) {
//console.log('complete', response);
},
error: function (response) {
console.log('error', response);
}
});
};
<?php
/**
* Plugin Name: WordPress JSONp Helper
* Plugin URI: http://www.jackreichert.com/2015/07/02/how-to-jsonp-ajax-to-ssl-in-wordpress-an-easier-way/
* Description: A paradigm for easy AJAX over SSL in WordPress using JSONP.
* Version: 0.1
* Author: jackreichert
* Author URI: http://www.jackreichert.com/
* License: GPL3
*/
class WP_AJAX_JSONp {
// actions on instatiation
function __construct() {
add_action( 'wp_enqueue_scripts', array( $this, 'wp_jsonp_scripts' ) );
}
// enqueue scripts
function wp_jsonp_scripts() {
wp_enqueue_script( 'wp_jsonp_script', plugins_url( '/jsonp.js', __FILE__ ), array( 'jquery' ) );
wp_localize_script( 'wp_jsonp_script', 'wp_jsonp_vars', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'wpAJAXNonce' => wp_create_nonce( 'wpAJAX-nonce' )
) );
}
}
$WP_AJAX_JSONp = new WP_AJAX_JSONp();
Here’s the example, you might say, wait a minute, don’t you get a callback from jQuery already? Sure, good luck using it. It’s a little funny ignoring that, but hey, this works nicely.
<?php
/**
* Plugin Name: another plugin
* Plugin URI: http://www.jackreichert.com/2015/07/02/how-to-jsonp-ajax-to-ssl-in-wordpress-an-easier-way/
* Description: An example of how you might use wp_jsonp.
* Version: 0.1
* Author: jackreichert
* Author URI: http://www.jackreichert.com/
* License: GPL3
*/
class Another_Plugin {
// actions on instatiation
function __construct() {
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
if ( is_plugin_active( 'jsonp/jsonp.php' ) ) { // plugin is active? Great we can use it!
add_action( 'wp_enqueue_scripts', array( $this, 'plugin_scripts' ) );
add_action( 'wp_ajax_wp_jsonp', array( $this, 'wp_jsonp_func' ) );
add_action( 'wp_ajax_nopriv_wp_jsonp', array( $this, 'wp_jsonp_func' ) );
}
}
// enqueue scripts
function plugin_scripts() {
wp_enqueue_script( 'wp_jsonp_call', plugins_url( '/scripts.js', __FILE__ ), array( 'wp_jsonp_script' ) );
}
// process the ajax calls
function wp_jsonp_func() {
if ( ! wp_verify_nonce( $_GET['ajaxSSLNonce'], 'wpAJAX-nonce' ) ) {
die ( 'Busted!' );
}
$response = array();
$method = $_GET['method'];
/**
* Send what should be processed here.
* Note: since you are sending the method via ajax, you MUST validate your data.
* If you don't you probably should check your SQL queries because you probably don't sanitize those either.
*/
switch ( $method ) {
case 'getStuff':
// if you get "hello world back, then it worked"
$response = "Hello World";
break;
default:
$response = "You didn't send any methods to process your variables?!";
break;
}
// response output
header( "content-type: text/javascript; charset=utf-8" ); // We're sending back a javascript function, remember?
header( "access-control-allow-origin: *" ); // This is needed for JSONP.
echo htmlspecialchars( $_GET['callback'] ) . '(' . json_encode( $response ) . ')'; // jQuery set up the callback for us.
// IMPORTANT: don't forget to "exit"
exit;
}
}
$Another_Plugin = new Another_Plugin();
jQuery(document).ready(function ($) {
// client side response processing of getStuff response
var getStuff = function (response) {
console.log(response);
}
jQuery(document).ready(function (e) {
// make the jsonp call: ajax_action, method, variables, callback
wp_jsonp("wp_jsonp", "getStuff", {variable: "hello world"}, getStuff);
});
});
Maybe I’m overthinking / over-complicating things, I don’t know, once it’s set up you can move really quickly, isn’t that the point of a framework?
Just one important note: make sure to validate the hell out of things because you’re giving that JS function a LOT of power.
I’d love to hear your thoughts, if you have suggestions for improving it, by all means, please comment below!