I am using a form and the 'get' method to offer users a return option to an unknown url that they came from within my site, as per the code below. I prefer this to just the browsers back button and it works without javascript.
The problem I am having is that some browsers (chrome, safari, there may be others) are adding a question mark to the end of the url they are referred back to. I don't want this for seo reasons.
My question is either:
1) Can I prevent the question mark within my php code somehow; or
2) Please could somebody show me how to redirect the url using htaccess, I potentially have urls that could end:-
.html?
.htm?
.php?
/?
Thanks in advance.
<?php
if (isset ($_SERVER['HTTP_REFERER']) ) {
$url = htmlspecialchars($_SERVER['HTTP_REFERER']);
echo '<br /><form action="' . $url . '" method="get">
<div id="submit"><input type="submit" value="Return to previous page" /></div>
</form>';
}
?>
The ? probably gets added because you're doing a GET request from a form.
Why not do something like:
<input type="button" onclick='document.location.href=<?php echo json_encode($url);?>'>;
use POST method instead of GET
Is it pertinent that you use a form for this? Why not use a hyperlink and style it to look however you want with CSS?
You could use try using a button instead of creating an input value that will be passed.
<form action="url" method="get">
<button type="submit">Return to previous page</button>
</form>
Instead of posting to random URLs (which is not really a good idea) consider using redirects
A solution would be
<?php
if (isset ($_SERVER['HTTP_REFERER']) ) {
$url = htmlspecialchars($_SERVER['HTTP_REFERER'],ENT_QUOTES,'UTF-8');
echo '<br /><form action="redirect.php" method="get">
<input type="hidden" name="return" value="'.$url.'">
<div id="submit"><input type="submit" value="Return to previous page" /></div>
</form>';
}
?>
then in redirect.php
<?php
if (isset ($_GET['return'] ) {
$url = $_GET['return'];
header('Location: '.$url, true, 303); // or 302 for compatibility reasons
echo 'Continue';
exit;
}else{
echo 'Error, no redirect specified';
}
you can replace action="GET" and $_GET with action="POST" and $_POST and it will work the same.
or simply
if (isset ($_SERVER['HTTP_REFERER']) ) {
$url = htmlspecialchars($_SERVER['HTTP_REFERER'],ENT_QUOTES,'UTF-8');
echo 'Return to previous page';
}
both will still create a new history entry in the browser.
In the htaccess you should have something like this:
RewriteEngine on
RewriteRule ^myPage-([a-zA-Z0-9_]*).html myPHPfile.php?var=$1
By the above piece added to your htaccess, when a URL like myPage-whatever.html is called, it's just like calling myPHPfile.php?var=whatever
Related
I think that this problem occurs often on a web application development. But I'll try to explain in details my problem.
I'd like to know how to correct this behavior, for example, when I have a block of code like this :
<?
if (isset($_POST['name'])) {
... operation on database, like to insert $_POST['name'] in a table ...
echo "Operation Done";
die();
}
?>
<form action='page.php' method='post' name="myForm">
<input type="text" maxlength="50" name="name" class="input400" />
<input type="submit" name="Submit" />
</form>
When the form gets submitted, the data get inserted into the database, and the message Operation Done is produced. Then, if I refreshed the page, the data would get inserted into the database again.
How this problem can be avoided? Any suggestion will be appreciated :)
Don't show the response after your create action; redirect to another page after the action completes instead. If someone refreshes, they're refreshing the GET requested page you redirected to.
// submit
// set success flash message (you are using a framework, right?)
header('Location: /path/to/record');
exit;
Set a random number in a session when the form is displayed, and also put that number in a hidden field. If the posted number and the session number match, delete the session, run the query; if they don't, redisplay the form, and generate a new session number. This is the basic idea of XSRF tokens, you can read more about them, and their uses for security here: http://en.wikipedia.org/wiki/Cross-site_request_forgery
Here is an example:
<?php
session_start();
if (isset($_POST['formid']) && isset($_SESSION['formid']) && $_POST["formid"] == $_SESSION["formid"])
{
$_SESSION["formid"] = '';
echo 'Process form';
}
else
{
$_SESSION["formid"] = md5(rand(0,10000000));
?>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
<input type="hidden" name="formid" value="<?php echo htmlspecialchars($_SESSION["formid"]); ?>" />
<input type="submit" name="submit" />
</form>
<?php } ?>
I ran into a similar problem. I need to show the user the result of the POST. I don't want to use sessions and I don't want to redirect with the result in the URL (it's kinda secure, I don't want it accidentally bookmarked). I found a pretty simple solution that should work for the cases mentioned in other answers.
On successfully submitting the form, include this bit of Javascript on the page:
<script>history.pushState({}, "", "")</script>
It pushes the current URL onto the history stack. Since this is a new item in history, refreshing won't re-POST.
UPDATE: This doesn't work in Safari. It's a known bug. But since it was originally reported in 2017, it may not be fixed soon. I've tried a few things (replaceState, etc), but haven't found a workaround in Safari. Here are some pertinent links regarding the issue:
Safari send POST request when refresh after pushState/replaceState
https://bugs.webkit.org/show_bug.cgi?id=202963
https://github.com/aurelia/history-browser/issues/34
Like this:
<?php
if(isset($_POST['uniqid']) AND $_POST['uniqid'] == $_SESSION['uniqid']){
// can't submit again
}
else{
// submit!
$_SESSION['uniqid'] = $_POST['uniqid'];
}
?>
<form action="page.php" method="post" name="myForm">
<input type="hidden" name="uniqid" value="<?php echo uniqid();?>" />
<!-- the rest of the fields here -->
</form>
I think it is simpler,
page.php
<?php
session_start();
if (isset($_POST['name'])) {
... operation on database, like to insert $_POST['name'] in a table ...
$_SESSION["message"]="Operation Done";
header("Location:page.php");
exit;
}
?>
<html>
<body>
<div style='some styles'>
<?php
//message here
echo $_SESSION["message"];
?>
</div>
<form action='page.php' method='post'>
<!--elements-->
</form>
</body>
</html>
So, for what I needed this is what works.
Based on all of the above solutions this allows me to go from a form to another form, and to the n^ form , all the while preventing the same exact data from being "saved" over and over when a page is refreshed (and the post data from before lingers onto the new page).
Thanks to those who posted their solution which quickly led me to my own.
<?php
//Check if there was a post
if ($_POST) {
//Assuming there was a post, was it identical as the last time?
if (isset($_SESSION['pastData']) AND $_SESSION['pastData'] != $_POST) {
//No, Save
} else {
//Yes, Don't save
}
} else {
//Save
}
//Set the session to the most current post.
$_session['pastData'] = $_POST;
?>
We work on web apps where we design number of php forms. It is heck to write another page to get the data and submit it for each and every form. To avoid re-submission, in every table we created a 'random_check' field which is marked as 'Unique'.
On page loading generate a random value and store it in a text field (which is obviously hidden).
On SUBMIT save this random text value in 'random_check' field in your table. In case of re-submission query will through error because it can't insert the duplicate value.
After that you can display the error like
if ( !$result ) {
die( '<script>alertify.alert("Error while saving data OR you are resubmitting the form.");</script>' );
}
No need to redirect...
replace die(); with
isset(! $_POST['name']);
, setting the isset to isset not equal to $_POST['name'], so when you refresh it, it would not add anymore to your database, unless you click the submit button again.
<?
if (isset($_POST['name'])) {
... operation on database, like to insert $_POST['name'] in a table ...
echo "Operation Done";
isset(! $_POST['name']);
}
?>
<form action='page.php' method='post' name="myForm">
<input type="text" maxlength="50" name="name" class="input400" />
<input type="submit" name="Submit" />
</form>
This happen because of simply on refresh it will submit your request again.
So the idea to solve this issue by cure its root of cause.
I mean we can set up one session variable inside the form and check it when update.
if($_SESSION["csrf_token"] == $_POST['csrf_token'] )
{
// submit data
}
//inside from
$_SESSION["csrf_token"] = md5(rand(0,10000000)).time();
<input type="hidden" name="csrf_token" value="
htmlspecialchars($_SESSION["csrf_token"]);">
I think following is the better way to avoid resubmit or refresh the page.
$sample = $_POST['submit'];
if ($sample == "true")
{
//do it your code here
$sample = "false";
}
I have a page that displays editing options if a certain POST variable is set, like so:
if(isset($_POST['manageType']) && ($_POST['manageType'] == 'edit'))
{
display_edit_gallery($title, $_GET['gallery']);
}
In display_edit, there's something like this:
<form action="manage/manage_gallery.php" method="post">
<input type="hidden" name="page" value="gallery_page.php" />
<input type="submit" name ="submit" value="Edit" />
</form>
I then do some stuff on manage_gallery.php and I finish with
header("Location: " . $_POST['page']);
exit();
The edit is performed, I am redirected, except it seems I'm redirected to the instance of gallery_page.php I just left. $_POST['manageType'] is still set (and so the editing options are still being displayed) despite the fact that nothing has been sent through post in manage_gallery.php. I do something similar with a 'delete image' option and the same happens. The image is deleted, but I need to reload the page for it not to be displayed anymore. It's like header() performs a 'back to the previous page' sort of thing.
I've used HTTP_REFERER instead and it works perfectly but I've been told it's not the safest option so I'd rahter avoid it . .
Change:
header("Location: " . $_POST['page']);
exit();
To:
echo <<<'EOD'
<script language="javascript">
window.history.go(-1);
</script>
EOD;
exit();
I'm making a page using php and I came to a point where I I have a if with two conditions and I need that if the conditions are true the button sends me to nother page, is that possible??
I have this code right now:
The button:
<form method="post">
<input type="submit" name="submit" class="buttonStyle" />
</form>
The PHP Script:
<?php
$homepage = "/site/nelson.php";
$currentpage = $_SERVER['REQUEST_URI'];
if(isset($_POST['submit']) && $homepage==$currentpage)
{
#Here should be the redirect
}
?>
Hope someone can help me :)
Thanks!
EDIT: found the solution, THANKS(!!!!!!!!!!!!) to all!
As the other answers suggested you should use the header function. You can also set a delay in the header so it will wait for a couple of seconds before redirecting like this:
header("Refresh: 5;url=yoururl.com");
If It's not working then you should take a look at this answer!
header("Location: http://my.domain.com/other_page");
Please note that for this to work, there can be no HTML already be sent to the client. Assuming your code snippet is in the same file, this means the PHP block should be placed before your HTML block.
<?php
$homepage = "/site/nelson.php";
$currentpage = $_SERVER['REQUEST_URI'];
if(isset($_POST['submit']) && $homepage==$currentpage) <--- the php script
{
header('Location: http://www.example.com/');
}
?>
<form method="post">
<input type="submit" name="submit" class="buttonStyle" /> <---the button
</form>
I have a textbox that allows users to search my website.
<form method="post" action="">
<input type="text" name="search" id="search" />
<input type="submit" name="submit" id="submit" value="Search" />
</form>
Upon the user clicking the "Search" button, how do create the following URL, and append the contents of the search box to end, whilst adding "_" in replace of any spaces?:
http://www.mysite.co.uk/find/this_is_my_search
Also, if somebody edits the search query in the URL, how do I update the search textbox to reflect this change, so the box contains the following
this is my search.
You need to handle that url using you 404 page. You can use $_SERVER['REQUEST_URI'] to get that path. For instance you could do this in your custom 404 page:
<?php
if (stripos($_SERVER['REQUEST_URI'], "/find/") == 0) //If url is yoursite.co.uk/find/
{
$searchterm = basename($_SERVER['REQUEST_URI']);
//Search for $searchterm
//Print the results
}
else
{
header("HTTP/1.0 404 Not Found");
}
?>
You can change action URL with JavaScript before submit event.
You can Use onSubmit event or use jquery
$('form').submit(function(){
$(this).attr('action', $('#search').val().replace(' ', '_'))
})
Change form method to get.. And also if you're using code igniter or other framworks you should be able to code like
$search = Uri:segment(2);
echo '<input type="submit" name="submit" id="submit" value="'.$search.'" />';
This can be achieved several ways.
Javascript
See StarLight's answer. It's simple and does the job, but you need to check for illegal URL-characters.
PHP redirect
Example: Set form action to 'search.php'.
<?php
$urlstr = urlencode(str_replace(' ', '_', $_GET['search']));
header("Location: http://www.mysite.co.uk/find/$urlstr");
exit;
?>
To update the textbox you need the following code on the page showing the search box.
<?php
// First get $urlstr from url.
$searchstr = str_replace('_', ' ', urldecode($urlstr));
$textboxvalue = (empty($searchstr)) ? 'Search' : $searchstr;
?>
<input type="submit" name="submit" id="submit" value="<?=$textboxvalue?>" />
I think that this problem occurs often on a web application development. But I'll try to explain in details my problem.
I'd like to know how to correct this behavior, for example, when I have a block of code like this :
<?
if (isset($_POST['name'])) {
... operation on database, like to insert $_POST['name'] in a table ...
echo "Operation Done";
die();
}
?>
<form action='page.php' method='post' name="myForm">
<input type="text" maxlength="50" name="name" class="input400" />
<input type="submit" name="Submit" />
</form>
When the form gets submitted, the data get inserted into the database, and the message Operation Done is produced. Then, if I refreshed the page, the data would get inserted into the database again.
How this problem can be avoided? Any suggestion will be appreciated :)
Don't show the response after your create action; redirect to another page after the action completes instead. If someone refreshes, they're refreshing the GET requested page you redirected to.
// submit
// set success flash message (you are using a framework, right?)
header('Location: /path/to/record');
exit;
Set a random number in a session when the form is displayed, and also put that number in a hidden field. If the posted number and the session number match, delete the session, run the query; if they don't, redisplay the form, and generate a new session number. This is the basic idea of XSRF tokens, you can read more about them, and their uses for security here: http://en.wikipedia.org/wiki/Cross-site_request_forgery
Here is an example:
<?php
session_start();
if (isset($_POST['formid']) && isset($_SESSION['formid']) && $_POST["formid"] == $_SESSION["formid"])
{
$_SESSION["formid"] = '';
echo 'Process form';
}
else
{
$_SESSION["formid"] = md5(rand(0,10000000));
?>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
<input type="hidden" name="formid" value="<?php echo htmlspecialchars($_SESSION["formid"]); ?>" />
<input type="submit" name="submit" />
</form>
<?php } ?>
I ran into a similar problem. I need to show the user the result of the POST. I don't want to use sessions and I don't want to redirect with the result in the URL (it's kinda secure, I don't want it accidentally bookmarked). I found a pretty simple solution that should work for the cases mentioned in other answers.
On successfully submitting the form, include this bit of Javascript on the page:
<script>history.pushState({}, "", "")</script>
It pushes the current URL onto the history stack. Since this is a new item in history, refreshing won't re-POST.
UPDATE: This doesn't work in Safari. It's a known bug. But since it was originally reported in 2017, it may not be fixed soon. I've tried a few things (replaceState, etc), but haven't found a workaround in Safari. Here are some pertinent links regarding the issue:
Safari send POST request when refresh after pushState/replaceState
https://bugs.webkit.org/show_bug.cgi?id=202963
https://github.com/aurelia/history-browser/issues/34
Like this:
<?php
if(isset($_POST['uniqid']) AND $_POST['uniqid'] == $_SESSION['uniqid']){
// can't submit again
}
else{
// submit!
$_SESSION['uniqid'] = $_POST['uniqid'];
}
?>
<form action="page.php" method="post" name="myForm">
<input type="hidden" name="uniqid" value="<?php echo uniqid();?>" />
<!-- the rest of the fields here -->
</form>
I think it is simpler,
page.php
<?php
session_start();
if (isset($_POST['name'])) {
... operation on database, like to insert $_POST['name'] in a table ...
$_SESSION["message"]="Operation Done";
header("Location:page.php");
exit;
}
?>
<html>
<body>
<div style='some styles'>
<?php
//message here
echo $_SESSION["message"];
?>
</div>
<form action='page.php' method='post'>
<!--elements-->
</form>
</body>
</html>
So, for what I needed this is what works.
Based on all of the above solutions this allows me to go from a form to another form, and to the n^ form , all the while preventing the same exact data from being "saved" over and over when a page is refreshed (and the post data from before lingers onto the new page).
Thanks to those who posted their solution which quickly led me to my own.
<?php
//Check if there was a post
if ($_POST) {
//Assuming there was a post, was it identical as the last time?
if (isset($_SESSION['pastData']) AND $_SESSION['pastData'] != $_POST) {
//No, Save
} else {
//Yes, Don't save
}
} else {
//Save
}
//Set the session to the most current post.
$_session['pastData'] = $_POST;
?>
We work on web apps where we design number of php forms. It is heck to write another page to get the data and submit it for each and every form. To avoid re-submission, in every table we created a 'random_check' field which is marked as 'Unique'.
On page loading generate a random value and store it in a text field (which is obviously hidden).
On SUBMIT save this random text value in 'random_check' field in your table. In case of re-submission query will through error because it can't insert the duplicate value.
After that you can display the error like
if ( !$result ) {
die( '<script>alertify.alert("Error while saving data OR you are resubmitting the form.");</script>' );
}
No need to redirect...
replace die(); with
isset(! $_POST['name']);
, setting the isset to isset not equal to $_POST['name'], so when you refresh it, it would not add anymore to your database, unless you click the submit button again.
<?
if (isset($_POST['name'])) {
... operation on database, like to insert $_POST['name'] in a table ...
echo "Operation Done";
isset(! $_POST['name']);
}
?>
<form action='page.php' method='post' name="myForm">
<input type="text" maxlength="50" name="name" class="input400" />
<input type="submit" name="Submit" />
</form>
This happen because of simply on refresh it will submit your request again.
So the idea to solve this issue by cure its root of cause.
I mean we can set up one session variable inside the form and check it when update.
if($_SESSION["csrf_token"] == $_POST['csrf_token'] )
{
// submit data
}
//inside from
$_SESSION["csrf_token"] = md5(rand(0,10000000)).time();
<input type="hidden" name="csrf_token" value="
htmlspecialchars($_SESSION["csrf_token"]);">
I think following is the better way to avoid resubmit or refresh the page.
$sample = $_POST['submit'];
if ($sample == "true")
{
//do it your code here
$sample = "false";
}