会话不适用于 ajaxRequest [如何使用会话变量计算 ajax 请求]

Posted

技术标签:

【中文标题】会话不适用于 ajaxRequest [如何使用会话变量计算 ajax 请求]【英文标题】:Session do not work on ajaxRequest [How to count ajax-request with session variable] 【发布时间】:2014-10-09 10:10:02 【问题描述】:

我有以下 php 代码,它计算对页面的每次访问。如果我直接打电话给对方,那是肯定的。如果我进行 Ajax 调用,它总是以 1 重新开始。

<?php
session_start();    
header('Access-Control-Allow-Origin: *');

        if (!isset($_SESSION['zaehler'])) 
          $_SESSION['zaehler'] = 1;
         else 
          $_SESSION['zaehler']++;
        
echo  $_SESSION['zaehler'];


?>

通过阅读以下内容,我了解到 ajax 调用与直接调用相同:Do AJAX requests retain PHP Session info? 只要边是打开的,我如何计算每个ajaxCall?

我正在做一个简单的 jquery ajaxCall:

    $.get( "http://www.huntinggrounds.de/aa.php", function( data ) 
         console.log( "dataResponse: ", data );
    ) .fail(function(jqXHR, textStatus ) 
        console.log( "error",textStatus);
       )
       .always(function() 
        console.log( "finished" );
       );

我制作了测试文件,testfile.html,只是一个黑屏。单击桌面并在控制台中查看计数器,php 文件为here。

【问题讨论】:

你能通过 AJAX 显示你用来做的代码吗? 你确定你的会话在这两种情况下都能开始吗? session_start();是我在 php 文件中的第一行 你需要在header()之前做session_start()。请参阅此处的第一个注释:php.net/manual/en/function.session-start.php 通过 jsonResponse = JSON.parse(data); 您将您的响应视为 JSON。这不是 JSON。你只是在回显一串数字。 【参考方案1】:

测试您的网页后,您的问题与您的域有关。

http://www.huntinggrounds.de/aa.html 工作正常,而不是 http://huntinggrounds.de/aa.html

出于安全原因,cookie 是针对每个域的。 PHP 在 http://huntinggrounds.de/aa.html 上设置的 Cookie 将无法在 http://www.huntinggrounds.de/aa.html 上工作,具体取决于您的配置。

要绕过这个问题,不要在你的 ajax 中设置完整的 URL。首选相对 URI。

$.get( "/collect?"+setParameter(defs),
 function( data ) 
      try 
             console.log("New count is : ",data);
           catch(e) 
             // if there is no response
             console.log( "No answer : ", data);
         
  ) 

【讨论】:

你说得对,它似乎有效。但是在将来的使用中,我会从不同的页面调用文件。我将在数据库中存储用户进行 ajax 调用的频率。所以这意味着我不能做那个服务器端? 您可以通过更新默认的 PHP 配置来允许子域共享会话的 cookie。尝试将其放在 PHP 页面的顶部(在 session_start 之前):ini_set('session.cookie_domain', '.huntinggrounds.de' ); 试试把这个指令直接放到php.ini中,可能是你不允许ini_set。 也试试这个:session_set_cookie_params(0, '/', '.huntinggrounds.de'); 不要运行我自己的服务器,所以我无权访问 php.ini。我可以检查一下吗【参考方案2】:

我看到你把这个放在 cmets 里了。

你是对的,它似乎有效。但是在将来的使用中,我正在调用 来自不同页面的文件。我将存储用户执行他的频率 数据库中的ajax调用。所以这意味着我不能做那个服务器端?

我对您的问题的问题是,为什么还要打扰会话,只需将其始终存储在数据库中。我将其发布为答案的原因是因为如果他们关闭浏览器会发生什么?在将其保存到数据库之前。

当然,您仍然希望会话正常工作。因为在服务器端,您可能希望从中提取他们的用户 ID 或其他信息。

解释会话问题: 我的钱花在了其他人提到的域路径( www.sub-domain -vs- no sub-domain )上,以说明您为什么会遇到会话 cookie 问题。这并不是真的你正在失去会话。但最有可能的是,如果您要查看存储在浏览器中的网站 cookie,您可能会拥有其中的 2 个。这意味着您正在为 www 使用一个会话。一个子域,一个用于没有域的站点。

您始终可以强制使用 www。在您的网站上也有一些 .htaccess 规则。 .htaccess - how to force "www." in a generic way?

无论如何,下面的细节取决于您的具体实现,这就是我不发布代码的原因。 在服务器端。

    在会话中验证使用,或者您可以在这里设置 IP 地址等...

    将用户 ID 用于数据库中的唯一字段,或用户 ID 和其他一些字段,如访问的日期或 URL。

    有一个数字字段“视图”等。而且,也许他们正在访问的网址的字段?

    在每个 ajax 请求中,将用户记录从数据库中拉出,增加视图字段并保存您想要的任何其他数据。

数据库查询将非常快,只需提取一行具有良好数字索引的行,例如用户 ID 等。

简而言之,我会跳过会话中的整个保存过程,因为就像我暗示的那样,如果他们关闭浏览器,你就会失去计数。此外,您如何知道何时将其保存在数据库中?当他们断开连接时,没有办法告诉服务器端,除了使用像 ajax 调用这样的心跳。您不能依赖他们正确注销。

我已经实施了一个类似的系统,以跟踪我们在工作中使用的一些外部承包商进行数据输入所花费的时间。

在那个植入中,我使用他们正在编辑的记录的 id 和他们的用户 ID 作为键,然后我有一个上次查看时间的时间戳,所以当 ajax 调用命中时,我会提取最后一次查看时间(如果它不到几分钟的时间)并且在一个单独的字段中,我保留了工作所花费的总秒数。然后通过一些基本的数学运算,我可以将新经过的秒数添加到总秒数中,哇哦,我可以相当准确地跟踪他们打开记录的时间。

【讨论】:

【参考方案3】:

正如在之前的答案中看到的那样,当您尝试从没有它们的第二个域 cookie 访问一个域 cookie 时,您的问题正在发生。

让两个域都为页面提供服务存在一个潜在的问题,那就是搜索引擎上的内容重复惩罚,因为 www 和非 www 访问计为两个站点。

您可以通过仅使用一个 URL 作为规范 URL 并重定向另一个来解决这两个问题。这可以通过 .htaccess 来完成,或者如果您在配置文件(在每个页面的开头加载)中没有这种服务器访问权限,请使用以下代码:

if ('www.' != substr($_SERVER['SERVER_NAME'], 0, 4)) 
    header('HTTP/1.1 301 Moved Permanently');
    header('Location: http://www.'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']);
    exit();

【讨论】:

以上是关于会话不适用于 ajaxRequest [如何使用会话变量计算 ajax 请求]的主要内容,如果未能解决你的问题,请参考以下文章

PHP会话不适用于多个WordPress页面

VaryByCustom 不适用于会话变量

ActionFilter 不适用于 AJAX 调用

Codeigniter 会话不适用于 PHP 7

Codeigniter 3 会话不适用于 PHP 7.1.4

NSURLSessionConfiguration timeoutIntervalForRequest 似乎不适用于后台会话