jhsachs Posted June 14, 2012 Share Posted June 14, 2012 Here's a problem for anyone who likes JavaScript puzzles and has too much time on their hands! For the sake of security, I wanted to pass all of a site's parameters via POST requests. This works fine as long as the design is limited to forms, but I was working with an existing site that has hundreds of links and dozens of buttons. I know it's possible to gin up a form with submit buttons that look like links, but the code is messy, and there were all sorts of situations that would have required special treatment; for example, buttons that contain images and links that span line breaks. I decided to solve the problem by coding links and buttons, and running a JavaScript function in the onclick event to move the URL and parameters into a hidden form, then submit the form. The idea was that a link like this... <a href="gerbils.php?wheel=yes">Gerbils!</a> ...would be recoded like this: <a onclick="return SetLoad(this);" href="gerbils.php?wheel=yes">Gerbils!</a> Every link would have to be changed, but the change would be simple and absolutely consistent. I tried it. It works. In Firefox 10. When I tried the fully "debugged" code in Internet Explorer 8 and Chrome 19, it failed in two different ways. IE appeared to execute the entire JavaScript function, then do a GET request as if the function had done nothing. Chrome wouldn't execute the function at all. At this point I decided to abandon the approach. I don't have experience debugging JavaScript in IE or Chrome, and a brief trial convinced me that in Chrome, at least, it would not be a walk in the woods. The technique I tried to implement seems elegant and useful, though... if it can be made to work in other browsers. That's the challenge. Whoever completes it will have my undying gratitude and a useful piece of code! Here's the code I've got: function SetLoad(id) { alert("We got here"); if ( typeof(id)=='string' ) { // This tag. var obj = document.getElementById(id); // id="x" onclick='return SetLoad("x")' } else if (id) { var obj = id; // onclick='return SetLoad(this);' } else { var obj = document.activeElement; // onclick='return SetLoad();' } if ( obj.tagName=='BUTTON' ) { // If it's a button var href = obj.value; // get its value } else { // else var href= obj.href; // it's an anchor; get its href. } var qPos = href.indexOf('?'); // Position of '?' var pars = ''; // Value of parameter string if any if (qPos>=0) { // If there is a '?' pars = href.substr(qPos+1); // par = the following substring href = href.substr(0,qPos); // href = the preceding substring } document.load.action = href; // Set the form's target document.load.params.value = pars; // Set the params field's value document.load.submit(); // Submit the form return false; } It operates on this form: <form name="load" method="POST" action="genX.php"> <?php passTokens() ?> <input type="hidden" name="params" value="xxxxxxxxxxx"/> </form> Each script that expects parameters must "unpack" them from the "params" parameter by calling this PHP function: /** * <p>Parse $_POST['params'] and replace it with its components.</p> * <p>This makes a script loaded by BodySuffix.inc's "load" form act like a conventionallyl loaded * script.</p> */ function parsePOST() { if ( !key_exists('params',$_POST) ) { return; } $params = $_POST['params']; if ( !isPOST('tokenS') || !isPOST('tokenP') || !isPOST('loadBy') ){ $msg = "tokenS, tokenP, or loadBy is missing:\n" . var_export($_POST,true); atrain_log(null,null,null,$msg); atrain_exit($msg); } $_POST = array( 'tokenS'=>$_POST['tokenS'], 'tokenP'=>$_POST['tokenP'], 'loadBy'=>$_POST['loadBy'] ); if ($params=='') { return; } foreach ( explode('&',$params) as $p ) { $pv = explode('=',$p); if ( count($pv)!=2) { $msg = "parsePOST ill-formed parameter: $params"; atrain_log(null,null,null,$msg); atrain_exit($msg); } $_POST[$pv[0]] = html_entity_decode($pv[1]); } } Quote Link to comment https://forums.phpfreaks.com/topic/264145-puzzlechallenge-making-a-link-or-button-perform-a-post-request/ Share on other sites More sharing options...
kicken Posted June 14, 2012 Share Posted June 14, 2012 Rather than modify all the links to add an onclick attribute, it would be better to setup a function to run when the dom is loaded which installs an onclick handler on all the link. If you only want to target certain links, give them a class that can be used to identify them. If your using a library such as jQuery then it is a fairly simple task: jQuery(function($){ $('a').click(function(e){ e.preventDefault(); //prevents the browser from following the link. //generate, populate, and submit form }); }); Using plain JS would not be much harder but I'll leave that as an exercise for the reader. Quote Link to comment https://forums.phpfreaks.com/topic/264145-puzzlechallenge-making-a-link-or-button-perform-a-post-request/#findComment-1353673 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.