{"id":52687,"date":"2021-07-12T03:01:30","date_gmt":"2021-07-11T17:01:30","guid":{"rendered":"http:\/\/www.rjmprogramming.com.au\/ITblog\/?p=52687"},"modified":"2021-07-11T14:00:47","modified_gmt":"2021-07-11T04:00:47","slug":"javascript-and-php-multiple-encoding-and-decoding-tutorial","status":"publish","type":"post","link":"https:\/\/www.rjmprogramming.com.au\/ITblog\/javascript-and-php-multiple-encoding-and-decoding-tutorial\/","title":{"rendered":"Javascript and PHP Multiple Encoding and Decoding Tutorial"},"content":{"rendered":"<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/encoding_decoding.php\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Javascript and PHP Multiple Encoding and Decoding Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/PHP\/encoding_decoding_multi.jpg\" title=\"Javascript and PHP Multiple Encoding and Decoding Tutorial\"  style=\"float:left;\" \/><\/a><p class=\"wp-caption-text\">Javascript and PHP Multiple Encoding and Decoding Tutorial<\/p><\/div>\n<p>Around here, we are very fond of dropdown (select element) &#8220;multiple&#8221; (attribute) selection mode.  That is a mode whereby you can select multiple options (helped out by using ctrl and command keyboard keys).  Unfortunately, order matters quite often, as with today&#8217;s exploits, and thoughts of the use of the &#8220;multiple&#8221; attribute often fly out the window, unless you can know ahead of time that the order you statically construct your dropdown&#8217;s options is always a good enough order for your purposes.<\/p>\n<p>So why not for today&#8217;s work?  Well, all the encoding and decoding options are totally &#8220;peers&#8221; in our thinking, and the user, if thinking of a &#8220;multiple&#8221; (ie. multi-layered) encoding\/decoding job, will not want to be dictated by the order we present the encoding and decoding options in our dropdown of yesterday, when we presented <a title='Javascript and PHP Encoding and Decoding Primer Tutorial' href='#jphpedpt'>Javascript and PHP Encoding and Decoding Primer Tutorial<\/a>.<\/p>\n<p>As an example, a user might want to see the end result of &#8230;<\/p>\n<p><code><br \/>\n[... To] = btoa(encodeURIComponent(base64_encode([From ...])));<br \/>\n<\/code><\/p>\n<p> &#8230; say.  Well, that is not in an order corresponding to the dropdown&#8217;s order.  So we should not resort to a &#8220;multiple&#8221; attribute mode dropdown mode of use.  What is the alternative?  Here, it is best to set up event logic for that dropdown&#8217;s &#8220;onchange&#8221; event, ours looking like <font color=blue>(fleshed out from yesterday)<\/font> &#8230;  <\/p>\n<p>&lt;?php echo &#8221;<br \/>\n<code><br \/>\n  function consider(sio) {<br \/>\n   <font color=blue>if (sio.value.trim() != '') {<br \/>\n    if (document.getElementById('topoption').innerHTML.indexOf(');') !=-1) {<br \/>\n     document.getElementById('topoption').innerHTML=document.getElementById('topoption').innerHTML.replace(' = ', ' = ' + sio.value + '(').replace(');', '));');<br \/>\n     ajaxit();<br \/>\n     if (document.getElementById('sende').innerHTML == '') {<br \/>\n       document.getElementById('sende').innerHTML='&lt;input style=background-color:orange; onclick=\\\"multi=true;\\\" id=xende name=complex value=\\\"' + document.getElementById('topoption').innerHTML + '\\\" type=submit&gt;&lt;\/input&gt;';<br \/>\n       document.getElementById('sviaextra').innerHTML='&lt;input style=background-color:orange; onclick=\\\"multi=true; document.getElementById(' + \\\"'\\\" + 'xende' + \\\"'\\\" + ').click();\\\" title=\\\"Do all the options individually clicked\\\" style=display:inline-block; id=zende value=\\\"+\\\" type=button&gt;&lt;\/input&gt;';<br \/>\n     } else {<br \/>\n       document.getElementById('xende').value=document.getElementById('topoption').innerHTML;<br \/>\n     }<br \/>\n    } else {<br \/>\n     document.getElementById('topoption').innerHTML='[... To] = ' + sio.value + '([From ...]);';<br \/>\n     ajaxit();<br \/>\n    }<br \/>\n   }<\/font><br \/>\n  }<br \/>\n<\/code><br \/>\n&#8220;; ?&gt;<\/p>\n<p>Notice the Javascript function name &#8220;ajaxit&#8221;?  Yes, in <font size=1>&#8220;[&#8230; To] = btoa(encodeURIComponent(base64_encode([From &#8230;])));&#8221;<\/font> we have a <font size=1>&#8220;[&#8230; To] = btoa<i>_Javascript<\/i>(encodeURIComponent<i>_Javascript<\/i>(base64_encode<i>_PHP<\/i>([From &#8230;])));&#8221;<\/font> mix of PHP and Javascript based encoding\/decoding calls required.  How best to flow, staying on the same webpage, without a complexity of form navigations (away from the current webpage)?  Use the good ol&#8217; &#8220;midair feeling&#8221; <a target=_blank title='Ajax information from Wikipedia ... thanks' href='http:\/\/en.wikipedia.org\/wiki\/Ajax_%28programming%29'>Ajax<\/a>\/<a target=_blank title='FormData object information' href='https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/FormData'>FormData<\/a> techniques, as per &#8230;<\/p>\n<p>&lt;?php echo &#8221;<br \/>\n<code><br \/>\n  var multi=false;<br \/>\n  var interim='';<br \/>\n  var xhr=null;<br \/>\n  var newform=null;<br \/>\n<br \/>\n  function showStuff(evt) {<br \/>\n  if (xhr != null) {<br \/>\n  if (xhr.readyState == 4) {<br \/>\n    if (xhr.status == 200) {<br \/>\n     interim=xhr.responseText;<br \/>\n    }<br \/>\n  }<br \/>\n  }<br \/>\n  }<br \/>\n<br \/>\n  function ajaxit() {<br \/>\n   var dto='';<br \/>\n   if (document.getElementById('tvia').value.indexOf('btoa') == 0 && interim == '') {<br \/>\n      dto=btoa(document.getElementById('tfrom').value);<br \/>\n    } else if (document.getElementById('tvia').value.indexOf('atob') == 0 && interim == '') {<br \/>\n      try {<br \/>\n      dto=atob(document.getElementById('tfrom').value);<br \/>\n      } catch(ecvd) { dto=' '; alert('You have some invalid characters for atob to handle.'); }<br \/>\n   } else if (document.getElementById('tvia').value.toUpperCase().indexOf('encodeURIComponent'.toUpperCase()) == 0 && interim == '') {<br \/>\n      dto=encodeURIComponent(document.getElementById('tfrom').value);<br \/>\n   } else if (document.getElementById('tvia').value.toUpperCase().indexOf('decodeURIComponent'.toUpperCase()) == 0 && interim == '') {<br \/>\n      dto=decodeURIComponent(document.getElementById('tfrom').value);<br \/>\n   } else if (document.getElementById('tvia').value.toUpperCase().indexOf('encodeURI'.toUpperCase()) == 0 && interim == '') {<br \/>\n      dto=encodeURI(document.getElementById('tfrom').value);<br \/>\n   } else if (document.getElementById('tvia').value.toUpperCase().indexOf('decodeURI'.toUpperCase()) == 0 && interim == '') {<br \/>\n      dto=decodeURI(document.getElementById('tfrom').value);<br \/>\n   } else if (document.getElementById('tvia').value.indexOf('btoa') == 0 && interim != '') {<br \/>\n      dto=btoa(interim);<br \/>\n    } else if (document.getElementById('tvia').value.indexOf('atob') == 0 && interim != '') {<br \/>\n      try {<br \/>\n      dto=atob(interim);<br \/>\n      } catch(ecvd) { dto=' ';  alert('You have some invalid characters for atob to handle.'); }<br \/>\n   } else if (document.getElementById('tvia').value.toUpperCase().indexOf('encodeURIComponent'.toUpperCase()) == 0 && interim != '') {<br \/>\n      dto=encodeURIComponent(interim);<br \/>\n   } else if (document.getElementById('tvia').value.toUpperCase().indexOf('decodeURIComponent'.toUpperCase()) == 0 && interim != '') {<br \/>\n      dto=decodeURIComponent(interim);<br \/>\n   } else if (document.getElementById('tvia').value.toUpperCase().indexOf('encodeURI'.toUpperCase()) == 0 && interim != '') {<br \/>\n      dto=encodeURI(interim);<br \/>\n   } else if (document.getElementById('tvia').value.toUpperCase().indexOf('decodeURI'.toUpperCase()) == 0 && interim != '') {<br \/>\n      dto=decodeURI(interim);<br \/>\n   }<br \/>\n   if (dto != '') {<br \/>\n   if (dto == ' ') {<br \/>\n   document.getElementById('topoption').innerHTML=document.getElementById('topoption').innerHTML.replace('atob(', '(');<br \/>\n   } else {<br \/>\n   interim=dto;<br \/>\n   }<br \/>\n   } else {<br \/>\n   xhr=new XMLHttpRequest();<br \/>\n   newform=new FormData();<br \/>\n   if (interim != '') {<br \/>\n   newform.append('from', interim);<br \/>\n   } else {<br \/>\n   newform.append('from', document.getElementById('tfrom').value);<br \/>\n   }<br \/>\n   newform.append('via', document.getElementById('tvia').value);<br \/>\n   newform.append('ajax', 'y');<br \/>\n   xhr.open('post', '.\/encoding_decoding.php', true);<br \/>\n   xhr.onreadystatechange = showStuff;<br \/>\n   xhr.send(newform);<br \/>\n   }<br \/>\n  }<br \/>\n<\/code><br \/>\n&#8220;; ?&gt;<\/p>\n<p>Again, you could (re-)try <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/PHP\/encoding_decoding.php-GETME\" title=\"encoding_decoding.php\">the changed PHP<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/encoding_decoding.php-GETME\" title=\"encoding_decoding.php\">&#8220;proof of concept&#8221; <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/encoding_decoding.php\" title=\"Click picture\">web application<\/a> code to see and try this for yourself.<\/p>\n<p><!--p>You can also see this play out at WordPress 4.1.1's <a target=_blank  href='\/\/www.rjmprogramming.com.au\/ITblog\/javascript-and-php-multiple-encoding-and-decoding-tutorial\/'>Javascript and PHP Multiple Encoding and Decoding Tutorial<\/a>.<\/p-->\n<hr>\n<p id='jphpedpt'>Previous relevant <a target=_blank title='Javascript and PHP Encoding and Decoding Primer Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/javascript-and-php-encoding-and-decoding-primer-tutorial\/'>Javascript and PHP Encoding and Decoding Primer Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/encoding_decoding.php\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Javascript and PHP Encoding and Decoding Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/PHP\/encoding_decoding.jpg\" title=\"Javascript and PHP Encoding and Decoding Primer Tutorial\"  style=\"float:left;\" \/><\/a><p class=\"wp-caption-text\">Javascript and PHP Encoding and Decoding Primer Tutorial<\/p><\/div>\n<p>The recent HTML form navigation work gobsmacked us mildly as we reconnected with the fact that a character like &#8220;~&#8221; is not changed (ie. encoded) by Javascript&#8217;s &#8220;encodeURIComponent&#8221; encoding function.  And then we figured that &#8220;~&#8221; can get you back to home directories on Linux and Unix, so presumably, could appear in a URL non-argument part (ie. the address of your web script).  There are others too, and so we decided to write a practical way for you to experiment with.<\/p>\n<p>Let&#8217;s show you the PHP <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/encoding_decoding.php_GETME\" title=\"encoding_decoding.php\">&#8220;proof of concept&#8221; <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/encoding_decoding.php\" title=\"Click picture\">web application<\/a> code, it being pretty short, below &#8230;<\/p>\n<p><code><br \/>\n&lt;?php<br \/>\n\/\/ encoding_decoding.php<br \/>\n\/\/ User experimentation with encoding and decoding systems<br \/>\n\/\/ RJM Programming<br \/>\n\/\/ July, 2021<br \/>\n$pfrom=\"The quick brown fox jumps over the lazy dog and tilde (~) followed closely behind, dragging along 0 Mostel!?\";<br \/>\n$pto=\"\";<br \/>\n$pvia=\"\";<br \/>\n$blurb=\"Please choose an encode or decode option below ...\";<br \/>\nif (isset($_POST['from']) && isset($_POST['via'])) {<br \/>\n  $pfrom=str_replace('+',' ',urldecode($_POST['from']));<br \/>\n  $pvia=str_replace('+',' ',urldecode($_POST['via']));<br \/>\n  if (strpos(urldecode($_POST['via']), \"base64_encode\") !== false) {<br \/>\n    $pto=base64_encode($pfrom);<br \/>\n    $blurb=$pvia;<br \/>\n  } else if (strpos(urldecode($_POST['via']), \"base64_decode\") !== false) {<br \/>\n    $pto=base64_decode($pfrom);<br \/>\n    $blurb=$pvia;<br \/>\n  } else if (strpos(urldecode($_POST['via']), \"urlencode\") !== false) {<br \/>\n    $pto=urlencode($pfrom);<br \/>\n    $blurb=$pvia;<br \/>\n  } else if (strpos(urldecode($_POST['via']), \"urldecode\") !== false) {<br \/>\n    $pto=urldecode($pfrom);<br \/>\n    $blurb=$pvia;<br \/>\n  }<br \/>\n}<br \/>\n<br \/>\necho \"<br \/>\n&lt;html&gt;<br \/>\n&lt;head&gt;<br \/>\n&lt;script type='text\/javascript'&gt;<br \/>\n  function consider(sio) {<br \/>\n  }<br \/>\n<br \/>     \u200b<br \/>\n  function maybeclient() {<br \/>\nocument.getElementById('tvia').value=document.getElementById('tvia').value.toLowerCase().replace('uri','URI').replace('component','Component');<br \/>\n    if (document.getElementById('tvia').value == '') {<br \/>\n      return false;<br \/>\n    } else if (document.getElementById('tvia').value.indexOf('base64') == 0) {<br \/>\n      return true;<br \/>\n    } else if (document.getElementById('tvia').value.indexOf('url') == 0) {<br \/>\n      return true;<br \/>\n    } else if (document.getElementById('tvia').value.indexOf('atob') == 0) {<br \/>\n      try {<br \/>\n      document.getElementById('tto').value=atob(document.getElementById('tfrom').value);<br \/>\n      } catch(ecvd) { alert('You have some invalid characters for atob to handle.'); }<br \/>\n    } else if (document.getElementById('tvia').value.indexOf('btoa') == 0) {<br \/>\n      document.getElementById('tto').value=btoa(document.getElementById('tfrom').value);<br \/>\n    } else if (document.getElementById('tvia').value.toUpperCase().indexOf('encodeURIComponent'.toUpperCase()) == 0) {<br \/>\n      document.getElementById('tto').value=encodeURIComponent(document.getElementById('tfrom').value);<br \/>\n    } else if (document.getElementById('tvia').value.toUpperCase().indexOf('decodeURIComponent'.toUpperCase()) == 0) {<br \/>\n      document.getElementById('tto').value=decodeURIComponent(document.getElementById('tfrom').value);<br \/>\n    } else if (document.getElementById('tvia').value.toUpperCase().indexOf('encodeURI'.toUpperCase()) == 0) {<br \/>\n      document.getElementById('tto').value=encodeURI(document.getElementById('tfrom').value);<br \/>\n    } else if (document.getElementById('tvia').value.toUpperCase().indexOf('decodeURI'.toUpperCase()) == 0) {<br \/>\n      document.getElementById('tto').value=decodeURI(document.getElementById('tfrom').value);<br \/>\n    }<br \/>\n    return false;<br \/>\n  }<br \/>\n&lt;\/script&gt;<br \/>\n&lt;\/head&gt;<br \/>\n&lt;body&gt;<br \/>\n&lt;h1&gt;User experimentation with encoding and decoding systems&lt;\/h1&gt;<br \/>\n&lt;h3&gt;RJM Programming - July, 2021&lt;\/h3&gt;<br \/>\n&lt;form onsubmit='return maybeclient();' method=POST action=.\/encoding_decoding.php&gt;<br \/>\n&lt;table style=width:90%; border=60&gt;<br \/>\n&lt;tr&gt;&lt;th&gt;From ... &lt;\/th&gt;&lt;th&gt; ... &lt;input type=submit value=via&gt;&lt;\/input&gt; ... &lt;\/th&gt;&lt;th&gt; ... To&lt;\/th&gt;&lt;\/tr&gt;<br \/>\n&lt;tr&gt;&lt;td&gt;&lt;textarea rows=30 style=width:100%; name=from id=tfrom&gt;\" . $pfrom . \"&lt;\/textarea&gt;&lt;\/td&gt;&lt;td style=vertical-align:top;text-align:center;&gt;&lt;select size=11 name=via id=tvia onchange=consider(this);&gt;<br \/>\n&lt;option value='\" . strtoupper($pvia) . \"'&gt;\" . $blurb . \"&lt;\/option&gt;<br \/>\n&lt;option value='base64_encode'&gt;<a target=_blank title='Information from home of PHP' href='https:\/\/www.php.net\/manual\/en\/function.base64-encode.php'>base64_encode<\/a>&lt;\/option&gt;<br \/>\n&lt;option value='base64_decode'&gt;<a target=_blank title='Information from home of PHP' href='https:\/\/www.php.net\/manual\/en\/function.base64-decode.php'>base64_decode<\/a>&lt;\/option&gt;<br \/>\n&lt;option value='btoa'&gt;<a target=_blank title='Information from w3schools for Javascript function' href='https:\/\/www.w3schools.com\/jsref\/met_win_btoa.asp'>btoa<\/a>&lt;\/option&gt;<br \/>\n&lt;option value='atob'&gt;<a target=_blank title='Information from w3schools for Javascript function' href='https:\/\/www.w3schools.com\/jsref\/met_win_atob.asp'>atob<\/a>&lt;\/option&gt;<br \/>\n&lt;option value='urlencode'&gt;<a target=_blank title='Information from home of PHP' href='https:\/\/www.php.net\/manual\/en\/function.urlencode.php'>urlencode<\/a>&lt;\/option&gt;<br \/>\n&lt;option value='urldecode'&gt;<a target=_blank title='Information from home of PHP' href='https:\/\/www.php.net\/manual\/en\/function.urldecode.php'>urldecode<\/a>&lt;\/option&gt;<br \/>\n&lt;option value='encodeURIComponent'&gt;<a target=_blank title='Information from w3schools for Javascript function' href='https:\/\/www.w3schools.com\/jsref\/jsref_encodeuricomponent.asp'>encodeURIComponent<\/a>&lt;\/option&gt;<br \/>\n&lt;option value='decodeURIComponent'&gt;<a target=_blank title='Information from w3schools for Javascript function' href='https:\/\/www.w3schools.com\/jsref\/jsref_decodeuricomponent.asp'>decodeURIComponent<\/a>&lt;\/option&gt;<br \/>\n&lt;option value='encodeURI'&gt;<a target=_blank title='Information from w3schools for Javascript function' href='https:\/\/www.w3schools.com\/jsref\/jsref_encodeuri.asp'>encodeURI<\/a>&lt;\/option&gt;<br \/>\n&lt;option value='decodeURI'&gt;<a target=_blank title='Information from w3schools for Javascript function' href='https:\/\/www.w3schools.com\/jsref\/jsref_decodeuri.asp'>decodeURI<\/a>&lt;\/option&gt;<br \/>\n&lt;\/select&gt;&lt;\/td&gt;&lt;td&gt;&lt;textarea readonly rows=30 style=width:100%; name=to id=tto&gt;\" . $pto . \"&lt;\/textarea&gt;&lt;\/td&gt;&lt;\/tr&gt;<br \/>\n&lt;tr&gt;&lt;td colspan=3&gt;&lt;input id=ende value='Encode or Decode' type=submit&gt;&lt;\/input&gt;&lt;\/td&gt;&lt;\/tr&gt;<br \/>\n&lt;\/table&gt;<br \/>\n&lt;\/body&gt;<br \/>\n&lt;\/html&gt;\";<br \/>\n<br \/>\n?><br \/>\n<\/code><\/p>\n<p>The space character is one to watch.  A client side HTML and Javascript form &#8220;encodeURIComponent&#8221;s any space to %20 but serverside PHP &#8220;urlencode&#8221;s a space to the &#8220;+&#8221; character.  This &#8220;+&#8221; is a legitimate character in data-URIs and we find we need to assume a &#8220;urldecode&#8221; of passed in characters, if they do not contain &#8230;<\/p>\n<ul>\n<li>data URIs &#8230; nor &#8230;<\/li>\n<li>Javascript code in the &#8220;head&#8221; element of a webpage<\/li>\n<li>some other real use of the &#8220;+&#8221; (eg. mathematical formula, north latitude sometimes, west longitude sometimes)<\/li>\n<\/ul>\n<p> &#8230; then we often, coming back from a form to serverside PHP, use &#8230;<\/p>\n<p><code><br \/>\n$varis = str_replace('+', ' ', urldecode($_POST['postedfieldname']));<br \/>\n<\/code><\/p>\n<p>Try it below if you like &#8230;<\/p>\n<p><iframe style=\"width:100%;height:800px;\" src=\"http:\/\/www.rjmprogramming.com.au\/PHP\/encoding_decoding.php\"><\/iframe><\/p>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d52678' onclick='var dv=document.getElementById(\"d52678\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/encodeURIComponent\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d52678' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d52687' onclick='var dv=document.getElementById(\"d52687\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/multiple\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d52687' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Around here, we are very fond of dropdown (select element) &#8220;multiple&#8221; (attribute) selection mode. That is a mode whereby you can select multiple options (helped out by using ctrl and command keyboard keys). Unfortunately, order matters quite often, as with &hellip; <a href=\"https:\/\/www.rjmprogramming.com.au\/ITblog\/javascript-and-php-multiple-encoding-and-decoding-tutorial\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,12,14,37],"tags":[69,2830,1653,3697,2661,2829,212,1607,3699,1606,367,2749,3700,1605,400,2730,652,2092,1631,2273,2076,3440,932,997,1866,1122,1319,1611,2831],"class_list":["post-52687","post","type-post","status-publish","format-standard","hentry","category-ajax","category-elearning","category-event-driven-programming","category-tutorials","tag-ajax","tag-atob","tag-base64","tag-base64_decode","tag-base64_encode","tag-btoa","tag-client","tag-decode","tag-decodeuri","tag-decodeuricomponent","tag-dropdown","tag-encode","tag-encodeuri","tag-encodeuricomponent","tag-event","tag-formdata","tag-javascript","tag-multiple","tag-onchange","tag-option","tag-order","tag-peer","tag-php","tag-programming","tag-select","tag-server","tag-tutorial","tag-urldecode","tag-urlencode"],"_links":{"self":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/52687"}],"collection":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/comments?post=52687"}],"version-history":[{"count":13,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/52687\/revisions"}],"predecessor-version":[{"id":52702,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/52687\/revisions\/52702"}],"wp:attachment":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/media?parent=52687"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/categories?post=52687"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/tags?post=52687"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}