Javascript and PHP Multiple Encoding and Decoding Tutorial

Javascript and PHP Multiple Encoding and Decoding Tutorial

Javascript and PHP Multiple Encoding and Decoding Tutorial

Around here, we are very fond of dropdown (select element) “multiple” (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’s exploits, and thoughts of the use of the “multiple” attribute often fly out the window, unless you can know ahead of time that the order you statically construct your dropdown’s options is always a good enough order for your purposes.

So why not for today’s work? Well, all the encoding and decoding options are totally “peers” in our thinking, and the user, if thinking of a “multiple” (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 Javascript and PHP Encoding and Decoding Primer Tutorial.

As an example, a user might want to see the end result of …


[... To] = btoa(encodeURIComponent(base64_encode([From ...])));

… say. Well, that is not in an order corresponding to the dropdown’s order. So we should not resort to a “multiple” attribute mode dropdown mode of use. What is the alternative? Here, it is best to set up event logic for that dropdown’s “onchange” event, ours looking like (fleshed out from yesterday)

<?php echo ”

function consider(sio) {
if (sio.value.trim() != '') {
if (document.getElementById('topoption').innerHTML.indexOf(');') !=-1) {
document.getElementById('topoption').innerHTML=document.getElementById('topoption').innerHTML.replace(' = ', ' = ' + sio.value + '(').replace(');', '));');
ajaxit();
if (document.getElementById('sende').innerHTML == '') {
document.getElementById('sende').innerHTML='<input style=background-color:orange; onclick=\"multi=true;\" id=xende name=complex value=\"' + document.getElementById('topoption').innerHTML + '\" type=submit></input>';
document.getElementById('sviaextra').innerHTML='<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></input>';
} else {
document.getElementById('xende').value=document.getElementById('topoption').innerHTML;
}
} else {
document.getElementById('topoption').innerHTML='[... To] = ' + sio.value + '([From ...]);';
ajaxit();
}
}

}

“; ?>

Notice the Javascript function name “ajaxit”? Yes, in “[… To] = btoa(encodeURIComponent(base64_encode([From …])));” we have a “[… To] = btoa_Javascript(encodeURIComponent_Javascript(base64_encode_PHP([From …])));” 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’ “midair feeling” Ajax/FormData techniques, as per …

<?php echo ”

var multi=false;
var interim='';
var xhr=null;
var newform=null;

function showStuff(evt) {
if (xhr != null) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
interim=xhr.responseText;
}
}
}
}

function ajaxit() {
var dto='';
if (document.getElementById('tvia').value.indexOf('btoa') == 0 && interim == '') {
dto=btoa(document.getElementById('tfrom').value);
} else if (document.getElementById('tvia').value.indexOf('atob') == 0 && interim == '') {
try {
dto=atob(document.getElementById('tfrom').value);
} catch(ecvd) { dto=' '; alert('You have some invalid characters for atob to handle.'); }
} else if (document.getElementById('tvia').value.toUpperCase().indexOf('encodeURIComponent'.toUpperCase()) == 0 && interim == '') {
dto=encodeURIComponent(document.getElementById('tfrom').value);
} else if (document.getElementById('tvia').value.toUpperCase().indexOf('decodeURIComponent'.toUpperCase()) == 0 && interim == '') {
dto=decodeURIComponent(document.getElementById('tfrom').value);
} else if (document.getElementById('tvia').value.toUpperCase().indexOf('encodeURI'.toUpperCase()) == 0 && interim == '') {
dto=encodeURI(document.getElementById('tfrom').value);
} else if (document.getElementById('tvia').value.toUpperCase().indexOf('decodeURI'.toUpperCase()) == 0 && interim == '') {
dto=decodeURI(document.getElementById('tfrom').value);
} else if (document.getElementById('tvia').value.indexOf('btoa') == 0 && interim != '') {
dto=btoa(interim);
} else if (document.getElementById('tvia').value.indexOf('atob') == 0 && interim != '') {
try {
dto=atob(interim);
} catch(ecvd) { dto=' '; alert('You have some invalid characters for atob to handle.'); }
} else if (document.getElementById('tvia').value.toUpperCase().indexOf('encodeURIComponent'.toUpperCase()) == 0 && interim != '') {
dto=encodeURIComponent(interim);
} else if (document.getElementById('tvia').value.toUpperCase().indexOf('decodeURIComponent'.toUpperCase()) == 0 && interim != '') {
dto=decodeURIComponent(interim);
} else if (document.getElementById('tvia').value.toUpperCase().indexOf('encodeURI'.toUpperCase()) == 0 && interim != '') {
dto=encodeURI(interim);
} else if (document.getElementById('tvia').value.toUpperCase().indexOf('decodeURI'.toUpperCase()) == 0 && interim != '') {
dto=decodeURI(interim);
}
if (dto != '') {
if (dto == ' ') {
document.getElementById('topoption').innerHTML=document.getElementById('topoption').innerHTML.replace('atob(', '(');
} else {
interim=dto;
}
} else {
xhr=new XMLHttpRequest();
newform=new FormData();
if (interim != '') {
newform.append('from', interim);
} else {
newform.append('from', document.getElementById('tfrom').value);
}
newform.append('via', document.getElementById('tvia').value);
newform.append('ajax', 'y');
xhr.open('post', './encoding_decoding.php', true);
xhr.onreadystatechange = showStuff;
xhr.send(newform);
}
}

“; ?>

Again, you could (re-)try the changed PHP “proof of concept” web application code to see and try this for yourself.


Previous relevant Javascript and PHP Encoding and Decoding Primer Tutorial is shown below.

Javascript and PHP Encoding and Decoding Primer Tutorial

Javascript and PHP Encoding and Decoding Primer Tutorial

The recent HTML form navigation work gobsmacked us mildly as we reconnected with the fact that a character like “~” is not changed (ie. encoded) by Javascript’s “encodeURIComponent” encoding function. And then we figured that “~” 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.

Let’s show you the PHP “proof of concept” web application code, it being pretty short, below …


<?php
// encoding_decoding.php
// User experimentation with encoding and decoding systems
// RJM Programming
// July, 2021
$pfrom="The quick brown fox jumps over the lazy dog and tilde (~) followed closely behind, dragging along 0 Mostel!?";
$pto="";
$pvia="";
$blurb="Please choose an encode or decode option below ...";
if (isset($_POST['from']) && isset($_POST['via'])) {
$pfrom=str_replace('+',' ',urldecode($_POST['from']));
$pvia=str_replace('+',' ',urldecode($_POST['via']));
if (strpos(urldecode($_POST['via']), "base64_encode") !== false) {
$pto=base64_encode($pfrom);
$blurb=$pvia;
} else if (strpos(urldecode($_POST['via']), "base64_decode") !== false) {
$pto=base64_decode($pfrom);
$blurb=$pvia;
} else if (strpos(urldecode($_POST['via']), "urlencode") !== false) {
$pto=urlencode($pfrom);
$blurb=$pvia;
} else if (strpos(urldecode($_POST['via']), "urldecode") !== false) {
$pto=urldecode($pfrom);
$blurb=$pvia;
}
}

echo "
<html>
<head>
<script type='text/javascript'>
function consider(sio) {
}

​
function maybeclient() {
ocument.getElementById('tvia').value=document.getElementById('tvia').value.toLowerCase().replace('uri','URI').replace('component','Component');
if (document.getElementById('tvia').value == '') {
return false;
} else if (document.getElementById('tvia').value.indexOf('base64') == 0) {
return true;
} else if (document.getElementById('tvia').value.indexOf('url') == 0) {
return true;
} else if (document.getElementById('tvia').value.indexOf('atob') == 0) {
try {
document.getElementById('tto').value=atob(document.getElementById('tfrom').value);
} catch(ecvd) { alert('You have some invalid characters for atob to handle.'); }
} else if (document.getElementById('tvia').value.indexOf('btoa') == 0) {
document.getElementById('tto').value=btoa(document.getElementById('tfrom').value);
} else if (document.getElementById('tvia').value.toUpperCase().indexOf('encodeURIComponent'.toUpperCase()) == 0) {
document.getElementById('tto').value=encodeURIComponent(document.getElementById('tfrom').value);
} else if (document.getElementById('tvia').value.toUpperCase().indexOf('decodeURIComponent'.toUpperCase()) == 0) {
document.getElementById('tto').value=decodeURIComponent(document.getElementById('tfrom').value);
} else if (document.getElementById('tvia').value.toUpperCase().indexOf('encodeURI'.toUpperCase()) == 0) {
document.getElementById('tto').value=encodeURI(document.getElementById('tfrom').value);
} else if (document.getElementById('tvia').value.toUpperCase().indexOf('decodeURI'.toUpperCase()) == 0) {
document.getElementById('tto').value=decodeURI(document.getElementById('tfrom').value);
}
return false;
}
</script>
</head>
<body>
<h1>User experimentation with encoding and decoding systems</h1>
<h3>RJM Programming - July, 2021</h3>
<form onsubmit='return maybeclient();' method=POST action=./encoding_decoding.php>
<table style=width:90%; border=60>
<tr><th>From ... </th><th> ... <input type=submit value=via></input> ... </th><th> ... To</th></tr>
<tr><td><textarea rows=30 style=width:100%; name=from id=tfrom>" . $pfrom . "</textarea></td><td style=vertical-align:top;text-align:center;><select size=11 name=via id=tvia onchange=consider(this);>
<option value='" . strtoupper($pvia) . "'>" . $blurb . "</option>
<option value='base64_encode'>base64_encode</option>
<option value='base64_decode'>base64_decode</option>
<option value='btoa'>btoa</option>
<option value='atob'>atob</option>
<option value='urlencode'>urlencode</option>
<option value='urldecode'>urldecode</option>
<option value='encodeURIComponent'>encodeURIComponent</option>
<option value='decodeURIComponent'>decodeURIComponent</option>
<option value='encodeURI'>encodeURI</option>
<option value='decodeURI'>decodeURI</option>
</select></td><td><textarea readonly rows=30 style=width:100%; name=to id=tto>" . $pto . "</textarea></td></tr>
<tr><td colspan=3><input id=ende value='Encode or Decode' type=submit></input></td></tr>
</table>
</body>
</html>";

?>

The space character is one to watch. A client side HTML and Javascript form “encodeURIComponent”s any space to %20 but serverside PHP “urlencode”s a space to the “+” character. This “+” is a legitimate character in data-URIs and we find we need to assume a “urldecode” of passed in characters, if they do not contain …

  • data URIs … nor …
  • Javascript code in the “head” element of a webpage
  • some other real use of the “+” (eg. mathematical formula, north latitude sometimes, west longitude sometimes)

… then we often, coming back from a form to serverside PHP, use …


$varis = str_replace('+', ' ', urldecode($_POST['postedfieldname']));

Try it below if you like …

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

This entry was posted in Ajax, eLearning, Event-Driven Programming, Tutorials and tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>