PHP:检测页面刷新

Posted

技术标签:

【中文标题】PHP:检测页面刷新【英文标题】:PHP: Detect Page Refresh 【发布时间】:2011-05-16 11:16:21 【问题描述】:

我有一个页面action.php,我在该页面上通过代码运行 SQL 查询,因此每当查看该页面时,查询的运行就像就像计算页面浏览量一样

<?php
mysqli_query("UPDATE ****");
?>

问题是当页面刷新时,查询运行 & PAGE REFRESH 被计为我想避免的 PAGE VIEW。

   问题:如何避免?

我正在寻找的是一个简单的解决方案,以便我可以检查

if( page was refresh ) //some condition

 do

【问题讨论】:

是否有任何 $_SERVER[''] 属性在从链接定向页面并刷新页面时会有所不同.. 如果是这样,那么解决这个问题就没有问题了跨度> @Junaid Saeed:为了清楚起见,您是否也希望不计算用户浏览离开页面然后又浏览回来的次数? $_SERVER 数组中的页面刷新没有变化,所以可以通过使用 Session 来完成 no.. 如果我想这样做,我会与我一起存储一些用户身份并计算不同的身份... 仔细想想,我意识到这不应该由 PHP 来处理... 【参考方案1】:

我找到了这个 sn-p here,它非常适合我:

$pageWasRefreshed = isset($_SERVER['HTTP_CACHE_CONTROL']) && $_SERVER['HTTP_CACHE_CONTROL'] === 'max-age=0';

if($pageWasRefreshed ) 
   //do something because page was refreshed;
 else 
   //do nothing;

【讨论】:

POST 请求无法“刷新”。只能再次发送。因此 chrome 以正确的方式执行此操作,并且不发送等效的缓存标头。 @user1032531【参考方案2】:

检测页面刷新的最佳方法。或不是?(Ctrl+F5,F5,Ctrl+R,回车)

$pageRefreshed = isset($_SERVER['HTTP_CACHE_CONTROL']) &&($_SERVER['HTTP_CACHE_CONTROL'] === 'max-age=0' ||  $_SERVER['HTTP_CACHE_CONTROL'] == 'no-cache'); 
if($pageRefreshed == 1)
    echo "Yes page Refreshed";
else
    //enter code here
    echo "No";

【讨论】:

使用 PHP 7.4.12 CGI 服务器本地开发机器和 Google Chrome 2020 年 11 月对我不起作用【参考方案3】:

你不能直接检测页面刷新,但是你可以使用cookie来模拟你想要的:

if (isset($_COOKIE['action'])) 
  // action already done
 else 
  setcookie('action');
  // run query

根据您的要求,您还需要决定何时删除 cookie 和/或再次执行该操作。

【讨论】:

【参考方案4】:

如果您只想为用户运行一次,我会设置一个会话 cookie,然后使用 if() 语句。

<?php
session_start();

if (!$_SESSION['loaded'])

    // insert query here


$_SESSION['loaded'] = true;

?>

【讨论】:

一旦设置了 $_SESSION['loaded'],我将无法在任何其他页面或具有不同参数的同一页面上进行此检查,例如您有水蛭页面...除非会话被销毁并且 ii 销毁会话,这意味着如果我的用户已登录,他\她将被注销...并且您在上面给出的这种语法将不起作用....正确的语法是 我已经解决了,我已经发布了这个解决方案作为我自己问题的答案..【参考方案5】:
    //here you get the url behind the domain.
    $currentPage = $_SERVER['REQUEST_URI']; 

    //if the session current page is not set.
    if(!isset($_SESSION['currentPage'])) 

      //set the session to the current page.
      $_SESSION['currentPage'] = $currentPage;     
    

    //check if the session is not equal to the current page
    if($_SESSION['currentPage'] != $currentPage)

       // if it's not equal you set the session again to the current page.
       $_SESSION['currentPage'] = $currentPage;

       //set the query you want to use
    

【讨论】:

【参考方案6】:

我已经解决了这个问题...... HURRAHHH,没有会话和没有 cookie

解决方案是 PHP : AJAX : javascript 的组合

您想在页面加载而不是在页面刷新上运行的查询通过 AJAX 调用运行它可以说我的功能是

function runQUERY()

    xmlhttp=new XMLHttpRequest();
    xmlhttp.open("POST","doIT.php",false);
    xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xmlhttp.send();

我可以通过执行以下操作简单地使用 Javascript 检查页面是新加载还是刷新

<head>
<script type="text/javascript">
function checkRefresh()

    if( document.refreshForm.visited.value == "" )
               
        // This is a fresh page load
            alert ( 'Fresh Load' );
        document.refreshForm.visited.value = "1";
            ..call you AJAX function here
    
    else
    
        // This is a page refresh
        alert ( 'Page has been Refreshed, The AJAX call was not made');

    

</script>    
</head>

<body onLoad="checkRefresh()">

<form name="refreshForm">
<input type="hidden" name="visited" value="" />
</form>

</body>
</html>

然后在您的 doIT.php 中简单地添加您要放入普通页面的 PHP 代码

<?php
mysql_query("UPDATE---------");
//put any code here, i won't run on any page refresh
?>

【讨论】:

这假定表单值在刷新后保留——这在 Firefox 和 IE 中是正确的,但在 Chrome 中不是。 我不认为你在 FF 和 IE 中看到的这种行为是任何标准的一部分,它可能会发生变化,这些浏览器版本之间的不一致,非面向未来,等等。Cookie 似乎是一个更可靠的解决方案。 确实,Chrome 并没有做错任何事,因为在页面刷新/后退/前进导航中保留表单值没有指定的行为。 正确的 方式是按预期呈现页面(通常为空白);保留表单值是某些浏览器可能会或可能不会做的事情。非常有趣的 hack,但至少部分有效。 当 javascript 未启用时,这似乎不起作用。 问卷的答案是错误的,误导了SO用户。【参考方案7】:

这可以在你的场景中工作:

if(isset($_GET["token"])) 
    $view_token = $_GET["token"];
 else 
    $new_views = $views + 1;
    // UPDATE VIEWS
    $view_token = substr(str_shuffle(str_repeat("0123456789abcdefghijklmnopqrstuvwxyz", 5)), 0, 5);
    header("Location: ?token=$view_token");

如果用户在 URL 中有令牌,则观看次数不会更新。因此,如果用户尝试刷新,它不会更新视图计数。当用户在 URL 中没有令牌时,查看计数会更新并刷新带有令牌的页面。它跳出框框思考,但确实有效!

【讨论】:

【参考方案8】:

您可以保存与当前页面关联的 cookie,如果单击任何链接,请使用新页面名称更新 cookie。 假设以上是在 Javascript 中完成的,您可以将此 updateCookie 信息发送到服务器以通知新的页面命中。

或者另一种方法是,您可以指定一个 HTTP HEADER 来指定页面上的 缓存过期 多长时间后,浏览器甚至不会发送您对页面加载/刷新的请求。

有关缓存的信息,请参阅http://www.mnot.net/cache_docs/#IMP-SCRIPT

另外,请查看 HTTP 中的 Etag 与 Expires - ETag vs Header Expires

【讨论】:

同意cookie,但是当明确刷新页面时,浏览器通常会再次向服务器请求该页面,而不管缓存设置如何。【参考方案9】:
if( $_SERVER['HTTP_CACHE_CONTROL'] == 'max-age=0')

    $_SESSION['status'] = null;<br>

【讨论】:

以上是关于PHP:检测页面刷新的主要内容,如果未能解决你的问题,请参考以下文章

为啥刷新页面后没有检测到Vuex? (努努特)

检测没有视图状态的页面刷新

反应 |如何检测页面刷新 (F5)

php如何避免刷新页面重复提交

用户名实时检测

使用onbeforeunload事件检测窗口是否刷新或关闭 .