Thanks to The Darkness for his javascript autoclicker and to Perkiset for both inspiration and his ajaxRequestor javascript. Perk's ajaxRequestor javascript is required for this to work, and it's available here:
http://www.perkiset.org/forum/javascript_ajax/ajax_requestor_class-t38.0.html Download the latest version, and put it in a file called "class.ajaxRequestor.js" located in a directory called "js". Or you can modify where the script is linked to in the below code if you'd prefer to put it somewhere else or call it something else.
What does this code do?For how complicated the process is, what it does is actually pretty simple. I wanted a way to asynchronously POST to a remote domain, and that's what it does.
What good is that to me?You might want to communicate something to a server on a remote domain, but don't need a response. So, rather than the hacky workarounds out there for getting XMLHTTPRequest to work cross-domain, you might choose to just fire off an invisible post.
What are the limitationsBecause of the "same origin policy" and other such silliness, you can't receive the server's response to your post, but in a lot of cases this is ok. There are hacks and workarounds to circumvent this restriction, but they're way outside the scope of a compact, easy-to-use code snippet. Also, since the post is firing from a page you own, the remote server will see whatever script you are instantiating this class from as the referer. That's not a terribly big deal, and the vast majority of services out there will accept the post regardless, provided it contains the right params.
So there you have it. If you'd like to "borrow" your surfer's IP in order to post to a remote domain, have at it!
Usage:
<?php
/*
Optionally, you can specify that RPX should send a GET request to the page (or another page) before the POST, or that it should be rendered inside a hidden div (not terribly important as the iframe that it creates is 1x1 anyway, but you never can be too paranoid).
*/
$RPX = new RPX('http://someremotedomain.com/postpage.html');
$RPX->addPostVar('foo','bar');
$RPX->dispatchPost();
?>
Class:
<?php
class RPX{
var $postURL;
var $getURL;
var $isHidden = 0;
var $doGetFirst = 0;
var $arrPostVars = array();
function RPX($postURL, $getURL = ''){
if(isset($_POST['RPXObj'])){
$RPXObj = stripslashes($_POST['RPXObj']);
$RPX = unserialize($RPXObj);
$RPX->printHTML();
exit;
}else{
$this->postURL = $postURL;
$this->getURL = $getURL;
}
}
function setHidden($hide = 1){
$this->isHidden = $hide;
}
function setDoGet($doGet = 1){
$this->doGetFirst = $doGet;
}
function addPostVar($name, $value){
$this->arrPostVars[$name] = $value;
}
function printHTML(){
$HTML = $this->buildHTML();
echo($HTML);
}
function buildHTML(){
$HTML = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'."\n".
'<html lang="en-US">'."\n".
'<body>'."\n";
if($this->isHidden)$HTML .= '<div style="display:none;" >';
if($this->doGetFirst)$HTML .= '<iframe src="'.$this->getURL.'" style="height:0px;width:0px;" ></iframe>'."\n";
$HTML .= '<form action="'.$this->postURL.'" method="POST" name="theForm" id="theForm" >'."\n";
$submitButton = 0;
foreach($this->arrPostVars as $name => $value){
if($name == "submit"){
$submitButton = 1;
$HTML .= '<input type="submit" name="_'.$name.'" id="_'.$name.'" value="'.$value.'" onclick="document.getElementById(\'theForm\').submit();" />'."\n";
}else{
$HTML .= '<input type="hidden" name="'.$name.'" id="'.$name.'" value="'.$value.'" />'."\n";
}
}
if(!$submitButton){
$HTML .= '<input type="submit" name="_submit" id="_submit" value="" onclick="document.getElementById(\'theForm\').submit();" />'."\n";
}
$HTML .= "</form>\n";
if($this->isHidden)$HTML .= '</div>';
$HTML .= "</body>\n</html>\n";
$HTML .= '<script type="text/javascript">
isIE = ( ( document.all ) && ( document.getElementById ) );
if( isIE )
document.getElementById("_submit").click();
else
document.getElementById("_submit").onclick();
</script>';
return $HTML;
}
function dispatchPost(){
$RPXObj = serialize($this);
echo('<script src="/js/class.ajaxRequestor.js" type="text/javascript"></script>'.
'<script type="text/javascript">'.
'ajax1 = new ajaxRequestor();'.
"ajax1.url = '".$_SERVER['PHP_SELF']."';".
"ajax1.postParam('RPXObj', '$RPXObj');".
'ajax1.onSuccess = handleAjax;'.
'ajax1.execute();'.
'function handleAjax(sender){
var ifrm = \'<iframe src="" name="postIframe" id="postIframe" style="height:1px;width:1px;"></iframe>\';
document.body.innerHTML += ifrm;
var ifram = document.getElementById(\'postIframe\');
ifram = (ifram.contentWindow) ? ifram.contentWindow : (ifram.contentDocument.document) ? ifram.contentDocument.document : ifram.contentDocument;
ifram.document.open();
ifram.document.write(sender.lastResponse);
ifram.document.close();
}'.
'</script>');
}
}
?>
TODO:
Patch some holes and do better input validation - as it stands a user could potentially send a malicious packet to the script (if he knew what was going on and how the object looked) in order to inject a malformed RPXObject.