Stop people from refreshing the page - php

Is there anyway for me to make it work so anyone who presses F5 or any refresh button will be moved to a different page, instead of it refreshing the page the user wants?
Something like :
If (refresh){
goto "link to hopme page"
}
If not is there anyway for me to not allow refreshing on a certain page?
I have some people that are are just refreshing non stop and it is killing my bandwidth. It is a game site so I don't want to ban the ip's.

Perhaps you should be focusing your effort instead on reducing the bandwidth your page is using. Explore the areas of image compression, page optimization and caching.

session_start();
if($_SESSION['hasbeenhere'] == 1)
{
// Page refreshed
}
else
{
$_SESSION['hasbeenhere'] = 1;
}
If the person doesn't have cookies enabled, this will fail. If someone goes to another page and comes back, it will shown as refreshed.
Overall, you can't do this in a way that is surefire, but this is 1 way to prevent someone from seeing the same page twice.
Because of your comment, if you want to stop people from pressing F5 200 times, try this.
$page = $_SERVER['REQUEST_URI'];
// Defaults
if(!isset($_SESSION[$page]['count']))
{
$_SESSION[$page]['count'] = 1;
$_SESSION[$page]['first_hit'] = time();
$_SESSION[$page]['banned'] = false;
}
else
{
$_SESSION[$page]['count']++; // Increase the counter
}
// If person is banned, end script
if($_SESSION[$page]['banned'] == true)
{
die();
}
if($_SESSION[$page]['first_hit'] < time() - 30)
{
$_SESSION[$page]['count'] = 1; // Reset every 30 seconds
}
if($_SESSION[$page]['count'] > 100)
{
$_SESSION[$page]['banned'] = true;
// Ban if they hit over 100 times in 30 seconds.
}

Why would you want to?
But no, there's no way that'll work consistently that can stop this.

In your PHP code, do the following:
if(isset($_SESSION["pagename-LAST_VIEWED"])) {
v = $_SESSION["pagename-LAST_VIEWED"])
if(time() - v < 15) {
// user is refreshing more than once per 15 seconds
// send them something else and die
}
}
$_SESSION["pagename-LAST_VIEWED"] = time();
Please ignore my crummy pseudo-PHP, it's not my daily language.
This will prevent both a page refresh (F5) and the user just clicking the bookmark again or pressing Enter in the address bar again.
You could also enable some aggressive caching meta tags and HTTP headers, which will prevent some refreshes from ever hitting your server, but the above code should be pretty scalable.
Another thing to consider: the root problem is your other code, not your users. Consider rewriting your page so it auto-updates the part they want to see via AJAX on a timed delay. This will give them incentive not to use Refresh, and will help your server cope by only having to refresh the small bit of data they want to see updated.

I have no idea if this would work, but could you listen for keystrokes with javascript, and on F5 keypress, do what you want.

I guess you could do this:
session_start();
if (isset($_SESSION['visited'])) {
header("Location: http://the.page/you/want");
} else {
$_SESSION['visited'] = true;
}

In order to stop F5 from refreshing, you'd have to not allow refreshing of any type. As a hack, you could try putting a timestamp in the querystring. On load, you can check the value of the timestamp and if it is in the past, redirect to another page. This would work if cookies are disabled.

The site itself does this with Javascript, so when you're editing something, you don't loose it by refreshing, going back, etc. There's probably some event defined by JQuery that lets you do this, so look into that, and on that event, redirect to the page you want (probably has to be within the same domain).

It seems to me that there is no good technical solution to this problem (the other answers covered that pretty well). If the users are constantly hitting refresh on this page, I'm guessing it's because they expect the page to change and they want up-to-the-second information. Perhaps you should take away their reason for wanting to refresh the page. The easiest way to do this would probably be making the page update itself (likely via AJAX). Thus the user can sit there and updates will just roll in -- no more hammering F5, which will cut down on your bandwidth, not to mention be a better user experience.

I just find out a very simple solution.
For me after i process all the $_POST information and save the ones i need into a $_SESSION var i do this:
$_SESSION['admin']['PID']=session_id();
$_SESSION['admin']['user_user']=$_POST['user'];
$_SESSION['admin']['user_pass']=$_POST['pass'];
$_SESSION['admin']['last_access_time']=time();
if($_SERVER['REQUEST_METHOD']==="POST")
{
header("LOCATION:".$_SERVER['PHP_SELF']."?p=redirected");
}
In my case i was trying to validate the user, and i have the problem that when someone logout and and go back and refresh the site load again, and with this simple if i finally solved it.
PD: ."?p=redirected" is only for testing porpouse

It's not answering your question directly but you can probably solve your issue with caching can't you?
If you send a header
Cache-Control: public,max-age=120
That should instruct the browser that it doesn't need to request the page again for 2 minutes and can just use the copy from it's cache. If course they can use control-f5 to force a refresh but it ought to help a lot?

Related

Check if cookies are enabled without redirect

I need on each page check if cookies are enabled.And use this code.
<?php
setcookie('COOK_CHK',uniqid(),time()+60*60*24);
if(!isset($_COOKIE['COOK_CHK'])){
echo"Cookies are disabled!";
exit;
}
session_start();
?>
However on the first check it gives me false until i don't refresh the page.I include this code in each page so can not redirect every time i load the page as it reduces performance.However i want to use it even if javascript is disabled.Any suggestions?
Can you use javascript? If so, all it takes is a check at the navigator.cookieEnabled variable.
It works in most modern browsers. You can read more about it here: http://www.w3schools.com/jsref/prop_nav_cookieenabled.asp
It's not possible because Cookies are in the browser, and PHP send them when the page has render, so will be available just in the second page.
A possible way to fix this is using javascript.
If you really should do it in PHP, for some crazy reason, send all your request to a main controller and save the state using other method, for example, write a var into a file, then redirect and in the next redirections you'll know if the cookies are enabled without needed any other redirection. Example:
$file = 'cookie_fake_'.$userIP;
if( !isset($_COOKIE['COOK_CHK']) && !file_exists($file) ){
file_put_contents($file, 'dummy');
setcookie('COOK_CHK',uniqid(),time()+60*60*24);
header('Location:/');
exit;
}
if(!isset($_COOKIE['COOK_CHK'])){
setcookie('COOK_CHK',uniqid(),time()+60*60*24);
echo"Cookies are disabled!";
exit;
}
Then you should write something to clean old files every hour or so, of course you can use a cache layer or a database or anything like that instead of writing a file.
Edit: The previous code will be really f** up if the user enables cookies and refresh the page, now I've fixed so it works at the second time it refresh. Not perfect but... You really should do this using javascript.
Cheers.

how to set php echo timer then move to another page

I wish after echo can wait about 2 second then move to another page ? how to do that ? using jquery ?
if($theme_added)
{
echo "Theme has been successfully added.";
window.location.href="manage_party_info.php";
}
You can try:
header('refresh: 2; url=http://www.example.net');
2 = number of seconds;
url = adress
For an instant redirect, you would do header("Location: manage_party_info.ph");
For a delayed one, however, you can output some JavaScript, or use a "meta refresh":
header("Refresh: 3; url=manage_party_info.php");
die("<p>Theme has been successfully added.</p>"
."<p>You will be redirected. Please click here if this page appears for more than five seconds.</p>");
Notice how I added a manual alternative with the link. This is an essential usability thing, because some users may have disabled the Refresh header in their browser (as it can be and sometimes is used for malicious purposes). You will face this problem if you use JavaScript/jQuery too, because users can disable JS.

Page reloads but doesn't hit server

I have the following Ajax logon script. index.php will set a session and then return something like {"status":true,"msgs":[],"url":"\/demo\/administrator\/index.php"}if the username and password checks out. The page then should reload, the PHP script will check if the session is set, and if so, will display the appropriate page.
"Sometimes" with FireFox 21.0 running on Windows 7, the page appears to reload, but then incorrectly re-displays the logon page. When I say "appears to reload", when using FireBug, I see the POST to the server, I then see the console.log "reload page" for a brief amount of time, and then the logon page is displayed. If I then manually reload the page, the session checks out, and the correct page is returned.
To troubleshoot, I put some syslog(LOG_INFO,"got here!"); in my PHP script, and I see it never got accessed a second time, thus my believe the server isn't getting hit after the reload. I've also checked the Apache access log, and I believe it only sees the first POST.
Can anyone let me know what is happening, and how to remedy it? Thank you
$.post('index.php',{task:'logon',username:username,password:password},
function (data)
{
if(data.status==true){
console.log('reload page');
//window.location.href = data.url;
window.location.href = window.location.href;
//window.location.reload();
}
else {msgs.html("<ul>"+mkList(data.msgs)+"</ul>");}
},'json'
);
This answer was really provided by Brian Lacy and user1600124, but they only left comments and didn't post this answer. So, please vote their comments up if you think this is a good answer.
Use window.location.reload(true) to submit data to server
If you don't explicitly tell the browser not to cache pages in the headers.. some browsers will still cache dynamic pages because the parameter that you send is the same.
As an alternate solution, you can append a timestamp to the url that would force browser to get content from server again.
also setting the pragma "no-cache" header for your page could help.
http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Avoiding_caching

Prevent displaying of previous pages after logout

i'm working at PHP application but i have a trouble, in fact when a user logged out and press after logging out the back button of the browser he can see the previous page as if the session has not been destroyed :(( i have tried all that i find here and on the web but it doesn't work :'(
Can I disable the back button?
http://blog.priyakant.com/2014/09/23/browser-back-button-prevent/
Summary:
Browser back button – Prevent displaying of previous pages after logout – Cookie based approach
Posted on September 23, 2014 by Priyakant Patel — Leave a comment
Prevent displaying of previous pages after logout
Client browser application caches page for performance reason. In this case when user clicks on back (browser back button) it shows previous page from cache.
Case 1 : User is still logged in.
it is OK to display content of previous page.
Case 2 : User is logged out.
Potentially next user can click on browser back button and can see content(s) of previous page(s).
This could be big problem in many applications. In financial application next user potential can see financial data. Or Medical / Patient related application this could be HIPAA violation and company can face big penalties.
So let’s get back to the point, How can solve this problem?
I am proposing HTTP Cookie based approach.
Steps:
Create HTTP Cookie from server side with sliding expiration. Which can be accessed from Client JavaScript (Note: Browser clears this Cookie upon expiration).
Clear this cookie upon logout
If you don’t find this Cookie, reload the page. In this case server re-authenticates page and if necessary it will redirect to the login page
That’s it, Done!
Here is my implementation using ASP.NET. Implementation will varies based on server technology but idea stays same.
(Server Side). Create HTTP Cookie from server side with sliding expiration
Response.SetCookie(new HttpCookie(“TimeoutCookieName”, "1") { Expires = DateTime.UtcNow.AddMinutes(10) });
//NOTE 10 == Session Timeout. This will be same as your application login session timeout.
(Server Side). Clear this cookie upon logout
Response.SetCookie(new HttpCookie(“TimeoutCookieName”, "1") { Expires = DateTime.UtcNow});
(Client Side) : (Following script must exists immediately after BODY tag)
window.preventBackButton = function () {
try {
if (document && (!document.cookie || document.cookie.indexOf('_tc=1') < 0)) {
window.document.body.style.display = 'none'; window.location = window.location;
}
} catch (e) { }
};
window.preventBackButton(); //Call immediately after body tag
Please find ASP.NET implementation as follow:
////C# Helper class - Start
using System;
using System.Web;
namespace MyHelpers {
public static class MyHtmlHelper {
public const string TimeoutCookieName = "_tc";
public static HtmlString PreventBackButtonScript(HttpResponseBase response) {
response.SetCookie(new HttpCookie(TimeoutCookieName, "1") { Expires = DateTime.UtcNow.AddMinutes(10) });
var clientScript = "window.-reventBackButton = function() {
try {
if(document && (!document.cookie || document.cookie.indexOf('" + TimeoutCookieName + "=1') < 0)) {
window.document.body.style.display='none'; window.location = window.location;
}
} catch(e) {}
};
window.preventBackButton();";
return new HtmlString(clientScript);
}
public static void SafeUnSetTimeoutCookie(this HttpResponseBase response) {
response.SetCookie(new HttpCookie(TimeoutCookieName, "0") { Expires = DateTime.UtcNow.AddYears(-5) });
}
}
}
////C# Helper class - End
//Shared\_Layout.cshtml
//Make sure not to include after logout OR login page
<html>
<body>
#MyHelpers.MyHtmlHelper.PreventBackButtonScript(Response)
.
.
<⁄body>
<⁄html>
You cannot disable the back button. If you can see the previously logged out user's page then your session checking script fails somewhere. Use a process script when you submit the logout form then redirect the currently logged out user to the main page (if applicable).
You can't. Browsers cache pages so they don't have to request it from a web server every time they load a page. When you hit the back button it loads the last page without asking the server.
It's probably more to do with the caching headers you're sending back on each page request. You have content that is only valid for a short time so you need to make sure you send headers back when you generate the page telling the browser not to cache it locally.
Example of disabling the page caching here http://www.w3schools.com/php/func_http_header.asp:
// Date in the past
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-cache");
header("Pragma: no-cache");
Are you clearing out the cache/session of the user? Even if they hit back I don't think it should keep them logged in if you clear their session on log out.
Edit: Prior to editing - by someone other than OP - this question asked if it is possible to disable the browser's back button. My original answer to that question is below. Also, I feel I need to clarify - the below approaches for essentially "breaking" the back button are not approaches I recommend or like. You should design your application to react sensibly when using basic browser features like the back button rather than try to prevent their use.
You cannot disable the back button on a user's browser. It's a fundamental feature of browsers which can't be overridden.
You can make it so that your application breaks (displays an error message, requiring the user to start over or re-submit a request) if the user goes back. It's a bad idea to do this, because it is really an admission that you didn't take the back button into account when you designed the application. Every application, even order forms, shopping carts etc, if designed correctly should be able to use the back button.
One approach I have seen for breaking on back button use is to pass a token on every URL within the application, and within every form. The token is regenerated on every page, and once the user loads a new page any tokens from previous pages are invalidated.
When the user loads a page, the page will only show if the correct token (which was given to all links/forms on the previous page) was passed to it.
The online banking application my bank provides is like this. If you use the back button at all, no more links will work and no more page reloads can be made - instead you see a notice telling you that you cannot go back, and you have to start over.
That said, I should remind you that making it so your application breaks when the user goes back is a bad idea and shows a poor application design.

PHP: Redirect to the same page, changing $_GET

I have this PHP piece of code that gets $_GET['id'] (a number) and do some stuff with this.
When its finished I need to increase that number ($_GET['id']) and redirect to the same page but with the new number (also using $_GET['id']).
I am doing something like this:
$ID = $_GET['id'];
// Some stuff here
// and then:
$newID = $ID++;
header('Location: http://localhost/something/something.php?id='.$newID);
exit;
The problem here is that the browser stop me from doing it and I get this error from the browser (Firefox) : "The page isn't redirecting properly. Firefox has detected that the server is redirecting the request for this address in a way that will never complete."
Some help here please!
NOTE: Some people suggested to do an internal loop, I mean a simple 'for' loop, but when i do this I get a time limit error (60 seconds) because the loop will take more time to finish..
It's an endless loop, each time the page loads, it changes the $_GET['id'] and redirects to itself again. You need a way to detect that the value is how you want it (final) and skip the redirect.
I suggest you add a second parameter after incrementing id, such as final so that when the page loads the second time, it skips the redirect because final was set.
i.e.:
if ($_GET['final'] != 1)
{
header('Location: http://localhost/something/something.php?id=' . $newID . '&final=1');
}
I think because the browser is in an endless loop.
If that code you posted is also on the something.php then it will always increment the number.
Also, there is no reason to do $newID = $ID++ because the ++ operator will increment that operand ($ID) automatically.
What you want is some form of logic to stop the loop. Perhaps...
if ($ID > 3) {
// don't redirect
}
However I can't really see how redirecting as a loop is ever a good idea, unless you are trying to do something that may be better achieved by a background process or cron job.
I would suggest that you redesign what you are doing. Redirecting back to self should never happen more than once, without a user input required to continue a loop.
As soon as the browser see's even the slightest possibility of and endless loop it will crash it. Even if you have if ($ID == 100) {..STOP..} by the time you reach 100 the browser will have already broken your loop, simply because by industry standards, that is immediately considered bad design and that is why your browser is already programmed to stop such a thing to begin with.
Can you share what it is you are actually trying to do with this loop. I am sure someone has a way to achieve what you want without doing it that way.
UPDATE TO COMMENT
Then you may want to look into AJAX or PHP API. I see what you mean, and want to do, that needs to be done in a controlled environment as opposed to a loop. The browser will never allow that kind of loop. So, there are a few ways to do that. You can do it with a client-side method where php delivers you a page to ajaxify the content from one source to another source. Or strictly php using php API methods to fetch the content and bring it directly back to the server. However, neither case is a beginners concept. :) if you know what I mean.
ob_start();
session_start();
if ( $_SESSION["id_old"] == $_GET['id']){ return false;}
$ID = $_GET['id'];
$newID = ++$ID;
$_SESSION["id_old"]= $newID;
header('Location: http://localhost/something/something.php?id='.$newID);
exit;
test localhost/something/something.php?id=22 -> localhost/something/something.php?id=23 return false;
It looks like you're trying to scrape a large amount of data from an external source. Why don't you run it as a local script on your own computer instead of through the browser? Then you don't have to worry about your script timing out or the browser detecting infinite redirects.
Well the answer is to do it locally in my localhost, using a 'for' loop and set_time_limit(0) to set the deafult 60 second limit of PHP to 0 (infinite) and not redirecting to the same page over and over again.

Categories