📜 ⬆️ ⬇️

We solve the problem of caching dynamic JavaScript code on the front-end WordPress

In the process of developing the anti-spam CleanTalk plugin for WordPress, we faced the problem of caching dynamic JavaScript code on the front end of sites. Namely, if you place JavaScript containing any pieces of code dynamically injected from the backend site, then if there is any page caching plug-in on the site, it becomes impossible to use the JavaScript code for its intended purpose.


Consider an example


In the backend we have a template JavaScript code,


<?php $html = ' <script type="text/javascript"> function ctSetCookie(c_name, value, def_value) { document.cookie = c_name + "=" + escape(value.replace(/^def_value$/, value)) + "; path=/"; } ctSetCookie("%s", "%s", "%s"); </script> '; $ct_checkjs_key = rand(0,100); //    $field_name = 'ct_checkjs'; //   $ct_checkjs_def = 0; //   $html = sprintf($html, $field_name, $ct_checkjs_key, $ct_checkjs_def); ?> 

An example of frontend output,


 <script type="text/javascript"> function ctSetCookie(c_name, value, def_value) { document.cookie = c_name + "=" + escape(value.replace(/^def_value$/, value)) + "; path=/"; } ctSetCookie("ct_checkjs", "455", "0"); </script> 

Accordingly, the JavaScript code gets into the cache in which the value parameter of the ctSetCookie function is unchanged on all pages of the site and is the same for all visitors, which makes it impossible to use JavaScript personally for each visitor. Consider solutions.


We use built-in means to disable caching


If the content caching plugin on WordPress is more or less popular, then it most certainly has the means to exclude the list of pages from the cache. For example, for WP Super cache, you can specify a line in the code of your plugin,


 define( "DONOTCACHEPAGE", true ); 

This will be enough so that the pages with your dynamic code do not fall into the cache. Cons of this approach



Let's look at another solution.


AJAX call backend


The essence of this approach is that at the frontend we place only static JavaScript code, and all that needs to be used is dynamically obtained from the backend of the site via an AJAX call. Sample code for frond,


 // //    admin-ajax.php // function sendRequest(url,callback,postData) { var req = createXMLHTTPObject(); if (!req) return; var method = "GET"; req.open(method,url,true); if (postData) req.setRequestHeader('Content-type','application/x-www-form-urlencoded'); req.onreadystatechange = function () { if (req.readyState != 4) return; if (req.status != 200 && req.status != 304) { return; } callback(req); }; if (req.readyState == 4) return; req.send(postData); return null; } var XMLHttpFactories = [ function () {return new XMLHttpRequest()}, function () {return new ActiveXObject("Msxml2.XMLHTTP")}, function () {return new ActiveXObject("Msxml3.XMLHTTP")}, function () {return new ActiveXObject("Microsoft.XMLHTTP")} ]; function createXMLHTTPObject() { var xmlhttp = false; for (var i=0;i<XMLHttpFactories.length;i++) { try { xmlhttp = XMLHttpFactories[i](); } catch (e) { continue; } break; } return xmlhttp; } // //   AJAX . // function ct_callback(req) { ct_cookie=req.responseText.trim(); ct_setCookie('ct_checkjs', ct_cookie); return null; } // //   // function ct_setCookie(name, value) { document.cookie = name+" =; expires=Thu, 01 Jan 1970 00:00:01 GMT; path = /"; document.cookie = name+" =; expires=Thu, 01 Jan 1970 00:00:01 GMT"; var date = new Date; date.setDate(date.getDate() + 1); setTimeout(function() { document.cookie = name+"=" + value + "; expires=" + date.toUTCString() + "; path = /;"}, 500); return null; } var ct_ajaxurl = 'http://wordpress.local/wp-admin/admin-ajax.php'; sendRequest(ct_ajaxurl+'?'+Math.random(),ct_callback,'action=ct_get_cookie'); 

Please pay attention to the design,


 ct_ajaxurl+'?'+Math.random() 

This technique is used to exclude caching, including the AJAX call.


Moving to the last listing, look at the backend,


 add_action( 'wp_ajax_nopriv_ct_get_cookie', 'ct_get_cookie',1 ); /** *    */ function ct_get_cookie() { global $ct_checkjs_def; $ct_checkjs_key = ct_get_checkjs_value(true); print $ct_checkjs_key; die(); } 

There is only one downside to this approach - your plugin makes 1 more call to the WordPress backend more. Taking into account the fact that hosting may not be the fastest, or more than a dozen plug-ins can be installed on WordPress, such a call will lead to an increase in the site response time.


Good luck in developing under WordPress!


')

Source: https://habr.com/ru/post/281955/


All Articles