I am trying to write a script which marks all my feed items as read within Google Reader. It should be as simple as posting 4 variables to an API link. However, the only way I can successfully make an HTTP POST to Google without getting a 400 error back is a simple HTML FORM POST as follows. I have tried PHP cURL but I get a 400 error from Google stating I have made a bad client request.
<form method="post" action="http://www.google.com/reader/api/0/mark-all-as-read">
<input type="hidden" name="s" value="user/10408189040522127442/state/com.google/reading-list" />
<input type="hidden" name="t" value="Your reading list" />
<input type="hidden" name="ts" value="<?php echo time(); ?>" />
<input type="hidden" name="T" value="<?php session_start(); echo $_SESSION['token']; ?>" />
<input type="button" value="Mark All As Read" /></form>
Submitting the same details using an HTML FORM (as I tried with cURL) works fine, successfully marking all items as read but because the FORM ACTION is set to an external site, you are redirected to it upon submission. To get around this I tried to do an AJAX FORM submission with the following, so there is no redirection but this doesn't work and nothing is submitted.
$(document).ready(function(){
$("input[type=button]").click(function() {
$.post($('form').attr("action"), $('form').formSerialize());
});
});
Can anyone advise?
1) Why does a cURL POST not work but a simple HTML FORM POST does?
2) Why can't I (silently) submit the HTML FORM with an AJAX submission?
Google may require certain headers to be set when doing the post, which is why it may be responding with a 400 error. Check that the same headers that are sent using the basic <form> are also set when submitting it using cURL.
Also, the reason why you can't $.post() to Google is due to the same origin policy.
Google does require an additional header for every post and some gets.
curl_setopt ($ch, CURLOPT_HTTPHEADER, array('Authorization: GoogleLogin auth=' . $auth));
to get the auth you need to hit https://www.google.com/accounts/ClientLogin
Take a look at this answer, Google Reader API?
Related
I'm trying to make a PHP page that lets you upload a document to telegram servers and than retrives a file_id which is stored in the json of the redirect page. After some tutorials on YT this is the code:
<?php
$botToken = "1099xxxxxx:AxxxE-g9qDI2Uxxxxxxxxxxxxxxxxxxxxxxxx";
$website = "https://api.telegram.org/bot".$botToken;
?>
<form action="<?php echo $website.'/sendPhoto' ?>" method="post" enctype="multipart/form-data">
<input type="text" name="chat_id" value="mychatid">
<input type="file" name="photo">
<input type="submit" value="send">
</form>
Redirect after submit
The goal is to retrive the file_id of the file and save it in a variable, possibly without opening another tab.
Thanks!
You've making the request to the Telegram API from the browser by submitting a form directly to it.
There is no way your PHP can get any information from that API that way.
As a side effect, you are giving your token (which should be kept secret) to every visitor who uses the form.
You need the browser to submit the form to a PHP program you control and then make the request to the Telegram API from your PHP and not from the browser.
The usual way to do this is with the cURL library.
Im having a site where I get the payment response sent out by the payment processor.My page is https and whereas my customers page is not.
I post the payment response this way
echo '<html>Redirecting to merchants website..<body>
<form id="myForm" action="'.$response_url.'" method="POST">
<input type="hidden" name="status" value="'.$response['status'].'"/>
<input type="hidden" name="customerReferenceNo" value="'.$data['customerReferenceNo'].'"/>
<input type="hidden" name="amount" value="'.$data['amount'].'"/>
<input type="hidden" name="paymentMode" value="'.$data['paymentMode'].'"/>
<input type="hidden" name="cardProvider" value="'.$data['cardProvider'].'"/>
<input type="hidden" name="orderID" value="'.$orderID.'"/>
<input type="hidden" name="mobileNo" value="'.$mobileNo.'"/>
<input type="hidden" name="email" value="'.$email.'"/>
</form>
<script>document.getElementById("myForm").submit();</script></body></html>';
as an hidden form post.But as Iam posting the values from an https to an http page,its popping up security warning in some browser as:
Although this page is encrypted, the information you have entered is to be sent
over an unencrypted connection and could easily be read by a third party.
Are you sure you want to continue sending this information?
I wonder if this is the correct way to post a response to an external url?Is what Iam doing is right?Is this th exact way I should post a payment response to an external url?
Please help out with some suggestion
As mentioned in the comment above you should definitely take care to post back to a https site. But instead of outputting a hidden form to the browser and posting from there it would be way better to use curl and so sent the data directly from the server to the payment processor.
See curl_exec in php documentation
I'm trying to get a POST response from a url and I can not get the response to print to my html page instead it just redirects me to the url in the action with the response.
Is there a way to grab the response with html? php?
Code of html page i'm using
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<form
method="post"
action="http://poster.decaptcher.com/"
enctype="multipart/form-data">
<input type="hidden" name="function" value="login">
<input type="text" name="username" value="client">
<input type="text" name="password" value="qwerty">
<input type="file" name="upload">
<input type="text" name="upload_to" value="0">
<input type="text" name="upload_type" value="0">
<input type="submit" value="Send">
</form>
</head><body></body></html>
Note: The url in the action will only show the response and nothing else is shown on the page.
Let's see if I can give this a try, because you seem to be a bit confused about how an HTML form works.
First and foremost, your website looks like so, correct?
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<form
method="post"
action="http://poster.decaptcher.com/"
enctype="multipart/form-data">
<input type="hidden" name="function" value="login">
<input type="text" name="username" value="client">
<input type="text" name="password" value="qwerty">
<input type="file" name="upload">
<input type="text" name="upload_to" value="0">
<input type="text" name="upload_type" value="0">
<input type="submit" value="Send">
</form>
</head><body></body></html>
One thing to point out before we explain an HTML form, is that you have your form in the <head> of the webpage. Any element which is supposed to be seen by the user (or anything that you want to appear within the browser's main viewing area) should be in the <body>. Failure to do this puts the browser into a "quirks mode", where it actually doesn't know what you're talking about and it makes its best guess to try and build the website that it thinks you wanted. Mind you that modern browsers are very good guessers, but you should still re-write it as:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<form
method="post"
action="http://poster.decaptcher.com/"
enctype="multipart/form-data">
<input type="hidden" name="function" value="login">
<input type="text" name="username" value="client">
<input type="text" name="password" value="qwerty">
<input type="file" name="upload">
<input type="text" name="upload_to" value="0">
<input type="text" name="upload_type" value="0">
<input type="submit" value="Send">
</form>
</body>
</html>
As far as explaining the <form> tag... When you submit a form in HTML, it actually loads the other website. It doesn't secretly send data in the background, it will take you away from the page you're viewing and take you to the page that you are sending the data to. At first this may sound silly. Why should it take you away from the page you're viewing just to send the data to another website? If you wanted to be redirected after sending the data, you'd redirect them there after sending the data.
The reason it's done this way is to greatly simplify the HTTP protocol. Whenever you load any website, you send and HTTP request. This request contains butt-loads of information. Among this information is:
Your IP address
What browser you're using
The page you were last visiting
How you accessed this page (clicked a link or typed the URL into the address bar)
The page you want to view (is it index.html or mysite.html?)
Any cookies related to that server
Any POST information (extra information which the server may or may not have asked for)
Every time the server receives one of these requests, it looks at all of the information and decides what to do. Usually a server will just look at the page you want to view and send it to you. Sometimes the page you want to view will need some extra work before it's ready to show, though. For instance, if a page ends in .php then it will search through the page for <?php, and everything after that point will be executed as a script. Only the output of the script is sent to the person who requested the page, not the script itself.
If you were to send your POST information to a website, wait 10 minutes, THEN go to the website, it would have no way of remembering that it was you who sent the post information before or what information you sent. Web servers have a very short attention span. For that reason if you sent a form to log into a website, then waited 10 minutes, then tried to view a member's only page- it would forget that you were logged in. For this reason it sends you the page as you're submitting the form. It does it while it still remembers that you're logged in, before it has a chance to forget. There's a good chance that the page it sends you will include a cookie which you can use to remind the server you were logged in next time you request a page.
If this made sense, then you should understand what happens when you submit a form. It doesn't just take your information and give it to the server. It sends that information to the server as part of an entire request, then the server sends you back a webpage and your browser displays that webpage. There is really only one way to send data to a server without redirecting you to that server afterwards. There are multiple ways to do this trick, however. You have to send a "dummy request", requesting a webpage with certain POST data, but ignoring the webpage that's returned.
In your example, you wanted to send data to http://poster.decaptcher.com. To do this without redirecting the user to http://poster.decaptcher.com, your easiest solution would be to use javascript and AJAX. Javascript has certain functions that allow you to send an HTTP request without reloading the page, then you let the javascript determine what to do with the page that's returned.
This is generally used when you want to reload a part of a webpage without reloading the whole thing. For instance, if you have a chat program and you want to update the chat window without refreshing the entire page. The javascript would request a webpage which contains ONLY the new lines of chat, minus any <html>, <head>, or <body> tags. It then takes those lines and displays them in the chat window.
You can, however, use AJAX to request a page and then ignore what's returned instead of display it on the page. By doing this you will have sent the POST data but not redirect the user.
Another option is to send the request to a third website, which can then send its own dummy request. For instance, submit the form to a PHP page that you own. The PHP script can then tell your server to send a dummy request to http://poster.decaptcher.com and ignore the response, then you can send them a webpage containing whatever you want.
Now that I've described both of these processes in adequate detail, I'll leave it as an exercise to the reader to figure out exactly how to do these. =)
The page refresh on submitted form is the default behavior of HTML.
For people who need to display the response into the same page without refresh, they will want to use Ajax. Here is how it could be done with jQuery:
$('#the_form').submit(function (e) {
e.preventDefault();
the_form = $(this);
$('#response_container').load(
the_form.attr('action')
, the_form.serialize()
);
})
the action defines the redirect to that page. If you want to catch the response, make your own script and place it in between the two. This is a bad way of doing it though. We developers call it hack coding. lol.
Not quite sure what you want to do. If you want to show the POST content on the page, just do this:
print_r($_POST);
If you want to see what is getting POSTed to the action URL, and you don't have access to that URL, just use the HTTP Headers plugin for Firefox.
action should go to a PHP file belonging to you! ie - action="/ProcessMyForm.php"
On that file, simply use $_POST and those form elements are in there, indexed by name, in an associative array.
Also - it may have been accidental, but post parameters dont go up in the URL like get, they are "behind the scenes" (invisible to the user) and also capable of being far larger.
PS - if you want to go to that other site afterwards, use header("Redirect: other-website-here.com")
First of all, mention your question specifically. If you want to fetch data from a URL than you can't use the form method="post". If you want to fetch data from URL, you have to use method "get". Calling print_r($_GET) can be used to retrieve data from HTML page to controller page.
I have a webpage. This webpage redirects the user to another webpage, more or less the following way:
<form method="post" action="anotherpage.php" id="myform">
<?php foreach($_GET as $key => $value){
echo "<input type='hidden' name='{$key}' value='{$value}' />";
} ?>
</form>
<script>
document.getElementById('myform').submit();
</script>
Well, you see, what I do is transferring the GET params into POST params. Do not tell me it is bad, I know that myself, and it is not exactly what I really do, what is important is that I collect data from an array and try submitting it to another page via POST. But if the user has JavaScript turned off, it won't work. What I need to know: Is there a way to transfer POST parameters by means of PHP so the redirection can be done the PHP way (header('Location: anotherpage.php');), too?
It is very important for me to pass the params via POST. I cannot use the $_SESSION variable because the webpage is on another domain, thus, the $_SESSION variables differ.
Anyway, I simply need a way to transfer POST variables with PHP ^^
Thanks in advance!
You CAN header redirect a POST request, and include the POST information. However, you need to explicitly return HTTP status code 307. Browsers treat 302 as a redirect with for GET, ignoring the original method. This is noted explicitly in the HTTP documentation:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8
Practically, this means in PHP you need to set the status code before the redirect location:
header('HTTP/1.1 307 Temporary Redirect');
header('Location: anotherpage.php');
However, note that according to the HTTP specification, the user agent MUST ask user if they are ok resubmitting the POST information to the new URL. In practical terms, Chrome doesn't ask, and neither does Safari, but Firefox will present the user with a popup box confirming the redirection. Depending on your operating constraints, maybe this is ok, although in a general usage case it certainly has the potential to cause confusion for end users.
No possibility to do this directly from server, as POST data should be sent by the browser.
But you can choose an alternative:
The prefilled form automatically submitted in your example could work, but as you wrote it's not really good practice and can leave users on a blank page
Receive GET arguments and POST them with curl (or any decent HTTP client) to the second site, then transfer the result to the browser. This is called a proxy and may be a good solution IMHO.
Do session sharing across domain, this can not be possible on all setups and can be complex.
Once setup is done, session sharing is almost transparent to PHP code. If you have more than one need for communication between the 2 domains it can be worth doing this.
Example with curl solution, code to run on domain 1:
//retrieve GET parameters as a string like arg1=0&arg1=56&argn=zz
$data = $_SERVER['QUERY_STRING'];
// Create a curl handle to domain 2
$ch = curl_init('http://www.domain2.com/target_script.php');
//configure a POST request with some options
curl_setopt($ch, CURLOPT_POST, true);
//put data to send
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
//this option avoid retrieving HTTP response headers in answer
curl_setopt($ch, CURLOPT_HEADER, 0);
//we want to get result as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//if servers support is and you want result faster, allow compressed response
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
//execute request
$result = curl_exec($ch);
//show response form domain 2 to client if needed
echo $result;
That's it, your client's browser won't even see domain 2 server, it will get only result from it. know if you want to redirect client to domain, do it with classic HTTP header.
header('Location: http://www.domain2.com');
Of course, this is demo code with hardcoded values, and there are 2 point left to you:
Security: query string should be filtered or recreated to transmit only needed parameters, and you should assert the server on domain 2 returned a 200 HTTP code.
Application logic should need a little adjustment on this part: if domain 2 app expects to get post data in the same request as visitor is coming it won't do it. From domain 2 point of view, the client doing POST request will be server hosting domain 1 not the client browser, it's important if client IP matters or other client checks are done on domain 2.
If the POST request serves to display client specific content you also had to do some server-side tracking to combine previously posted data with the visitor being redirected.
You could hack something together like the following... (I'm not saying you should however!):
$res = "<form action='/path/to/new/page' method='POST' id='redirectHack'>
<input type='hidden' id='postVar1' name='postVar1' value='12345'>
<input type='hidden' id='postVar2' name='postVar2' value='67890'>
</form>
<script>
document.getElementById('redirectHack').submit()
</script>";
die($res);
Store your data in a session and then use GET.
No. You can't do header redirect with POST. You have 2 options,
You can use GET instead if the destination accepts either POST or GET.
We add a button in rare cases that the Javascript is turned off.
Here is an example,
<noscript>
<div>
<input type="submit" value="Continue"/>
</div>
</noscript>
This will show a continue button if Javascript is off so user can click to continue.
It is possible. In this situation I would use cURL:
$url = 'http://domain.com/get-post.php';
foreach($_GET as $key=>$value) {
$fields_string .= $key.'='.$value.'&';
}
rtrim($fields_string,'&');
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
As a sample of what #Charles indicates, here is a working php PayPal buy form that:
Checks the input with javascript. If OK, it submits it, else displays an alert.
Checks the input with php. If OK, it creates the redirect headers and gets rid of the body HTML, else it shows the same form again.
Note that:
Inputs should be rechecked on the server, as a browser's inputs can be nefariously manipulated.
No HTML can be output before the header commands, as they will be ignored with a php warning.
Javascript can only check the inputs for valid values, but without AJAX, will not be able to check the server for whatever the user wants before submission. Therefore, this method is the complete non-javascript process.
No HTML is needed if the redirect target (like PayPal) is only processing the POST data. Targets for humans do, of course!
Unfortunately, 4 means that you cannot send just a subset or even a complete other set of values to the new url, AND have the target page processing the POST data open in the user's browser. You cannot do this by manipulating the $_POST array (it seems to be just a PHP copy of the actual data). Perhaps someone knows how to modify the real POST data set?
From 5, there is no opportunity to gather private information on the
original form, and just send only the payment information on the
form to PayPal or whomever, via the user's browser for their explicit payment approval. That means AJAX is needed to do that by
using two forms, one holding the private info with no button, and
the other form with the PayPal buy button that uses AJAX to submit
the other form, and depending upon the result, submit its own form.
You could use fields that PayPal doesn't use, but they are still
getting the info, and we don't know what they have trawling over
submitted form data.
Rather than using AJAX as in 6, it would be a lot simpler to have 3 versions of the form:
Initial to capture the private data.
If problem, re-show form with submitted data and indication of incorrect data or backend problem.
If OK, a PayPal form, submitted automatically by javascript at
the bottom of the page (form.submit()), or a request to submit manually by a button if no javascript.
<?php
// GET POST VARIABLES, ELSE SET DEFAULTS
$sAction=(isset($_POST['action'])?$_POST['action']:'');
$nAmount=(int)(isset($_POST['action'])?$_POST['amount']:0);
// TEST IF AMOUNT OK
$bOK=($nAmount>=10);
/*
TYPICAL CHECKS:
1. Fields have valid values, as a backup to the javascript.
2. Backend can fulfil the request.
Such as whether the requested stock item or appointment is still available,
and reserve it for 10-15 minutes while the payment goes through.
If all OK, you want the new URL page, such as PayPal to open immediately.
*/
// IF OK
if($bOK){
// CHANGE HEADER TO NEW URL
$sURL='https://www.paypal.com/cgi-bin/webscr';
header('HTTP/1.1 307 Temporary Redirect');
header('Location: '.$sURL);
}
?>
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Sample post redirection</title>
</head>
<body>
<?php
// IF NO ACTION OR NOT OK
if(($sAction=='')||!$bOK){
?>
<h1>Sample post redirection</h1>
<p>Throw money at me:</p>
<form name="pp" action="<?=$_SERVER['REQUEST_URI']?>" method="post" onsubmit="check_form(this)">
<!-- <input type="hidden" name="amount" value="<?=$nAmount?>" /> -->
<input type="hidden" name="business" value="paypal.email#yourdomain.com" />
<input type="hidden" name="cmd" value="_xclick" />
<input type="hidden" name="lc" value="AU" />
<input type="hidden" name="item_name" value="Name of service" />
<input type="hidden" name="item_number" value="service_id" />
<input type="hidden" name="currency_code" value="AUD" />
<input type="hidden" name="button_subtype" value="services" />
<input type="hidden" name="no_note" value="0" />
<input type="hidden" name="shipping" value="0.00" />
<input type="hidden" name="on0" value="Private" />
<input type="hidden" name="os0" value="Xxxx xxxxx xxxxx" />
<p>Amount $<input id="amount" type="text" name="amount" value="<?=$nAmount?>" /> $10 or more.</p>
<p><button type="submit" name="action" value="buy">Buy</button></p>
</form>
<p>If all is OK, you will be redirected to the PayPal payment page.<br />
If your browser requires confirmation, click the <cite>OK</cite> button.</p>
<script>
// JS AT END OF PAGE TO PREVENT HTML RENDER BLOCKING
// JS FUNCTION FOR LOCAL CHECKING OF FIELD VALUES
function check_form(oForm){
// USE TO DETERMINE IF VALUES CORRECT
var oAmount=document.getElementById('amount');
var nAmount=oAmount.value;
var bOK=true;
var bOK=(nAmount>=10); // EXAMINE VALUES
// IF NOT OK
if(!bOK){
// INDICATE WHAT'S WRONG, ALERT ETC
alert('Stingy #$#&. Pay more!!');
// BLOCK FORM SUBMIT ON ALL BROWSERS
event.preventDefault();
event.stopPropagation();
return false;
}
}
</script>
<?php
}
?>
</body>
</html>
In a POST Redirect GET situation, ( see https://en.wikipedia.org/wiki/Post/Redirect/Get ) it is acceptable to use the session variable as the method of transporting the data.
<?php
session_start();
// return is the name of a checkbox in the post-redirect-get.php script.
if(isset($_POST['return'])) {
// We add some data based on some sort of computation and
// return it to the calling script
$_SESSION['action']="This string represents data in this example!";
header('location: post-redirect-get.php');
}
How do you go about redirecting a browser and sending a HTTP POST request in PHP? A header("Location: file.php?foo=bar") of HTTP POST requests, if you will.
You can't - HTTP does not allow this - if you want to pass arguments via a redirect they have to be embedded into the URL as GET vars.
C.
This does not redirect the browser but it can perform a POST request.
Curl Manual
Curl POST Example
PHP POST Without Curl
To redirect the browser i'd suggest using Javascript.
An example form that does POST and redirect
<FORM action="http://somesite.com/prog/adduser" method="post">
<P>
<LABEL for="firstname">First name: </LABEL>
<INPUT type="text" id="firstname"><BR>
<LABEL for="lastname">Last name: </LABEL>
<INPUT type="text" id="lastname"><BR>
<LABEL for="email">email: </LABEL>
<INPUT type="text" id="email"><BR>
<INPUT type="radio" name="sex" value="Male"> Male<BR>
<INPUT type="radio" name="sex" value="Female"> Female<BR>
<INPUT type="submit" value="Send"> <INPUT type="reset">
</P>
</FORM>
I'm not sure why you would have any need for this, however it is not possible in any server-side language.
You could use a javascript library such as jQuery to request a page using a post request
I don't believe you can get a browser to POST data by redirecting it in the middle of a request. You're limited to GET. If you want a browser to POST something you need to construct a <form> and submit it. (Or use an AJAX request.)
PHP doesn't have anything like this. To fulfill your example, you can just simply say $_GET['foo'] = 'bar'; include("file.php"), however the URL given to the browser will not be changed.
Similar question: Code Translation: ASP.NET Server.Transfer in PHP
This question was asked here How do you POST to a page using the PHP header() function?.
Someone commented that if you already had the data why do you need to post it anywhere, why can't you just act on the data in that page?
If you need to transfer data when you redirect without showing data in the URL, you can use $_SESSION, first store data into session then redirect the page, after redirection get data from session and destroy the session data..
OK, if you need to transfer data to other site without showing in the URL, u have to use Javascript instead... like transfer data to payPal. just make a form and write a javascript code to submit the form automatically on page load. below is the sample code:
<form name="myform" action="handle-data.php">
Search: <input type='text' name='query' />
Search
</form>
<script type="text/javascript">
function submitform()
{
document.myform.submit();
}
</script>