【问题标题】:PHP session variables not preserved with ajaxajax 不保留 PHP 会话变量
【发布时间】:2023-03-19 23:48:01
【问题描述】:

我有一个单页网站,它使用 AJAX 加载新的 php 文件并更新显示。

我在主页上启动我的 php 会话,但是当我使用 ajax 更新内部 html 时,我需要这些会话变量来加载新的 php 文件。

这篇文章与这篇文章类似:PHP Session Variables Not Preserved。但我查了一下,我的 php.ini 有 session.use_cookies = 1

主页 PHP:

<?php 
session_start();
if(isset($_SESSION['views']))
{$_SESSION['views']=$_SESSION['views']+1;}
else
{$_SESSION['views']=1;}
?>

在用户输入之后,我使用 ajax 调用一个 php 文件并加载页面的一个小节:

<?php    
if(isset($_SESSION['views']))
    { echo "Views: " . $_SESSION['views'];} 
    else 
    { echo "Views: NOT SET";}
?>

谁能告诉我我错过了什么重要的步骤?谢谢。

更新:在向主页面和子页面添加 session_id() 调用后,我看到两个页面具有相同的 Session_ID。但是,它仍然无法提取会话变量,如果我确实为它分配了一个值,两个同名的会话变量将保持相互独立。

回答这个问题提出的问题: 我发现我必须在我的 php.ini 文件中设置一个静态 session_save 路径。对于大多数付费虚拟主机服务,它们只有一个默认的会话容器,但它会受到负载平衡的影响。多么放松。

【问题讨论】:

  • 当我在新文件中使用 session_start() 时,它会创建一个新会话。无论如何要链接这些会话吗?
  • “链接”会话的是会话cookie,它应该在HTTP请求的Cookie头中...
  • 您没有使用负载平衡的网络服务器,是吗? (当 PHP 会话使用默认的基于文件的后备存储时,主机自然无法共享会话信息)
  • 我正在使用付费虚拟主机提供商 IPage,这很可能就是这种情况。我想要做的事情是创建一个本地灯服务器,看看它是否与我的付费托管服务提供商做同样的事情。感谢您的输入。
  • 同意在本地服务器上进行测试会增加有用的信息。 PHP 允许您定义和注册自己的方法来读取和写入会话信息,因此如果您的托管服务提供商为持久存储提供数据库访问权限,那么您可以使用数据库而不是基于文件的 PHP 会话后备存储,这应该可以正常工作负载平衡的环境。

标签: php ajax session-variables


【解决方案1】:

我认为您在 Ajax 调用的页面上缺少 session_start()

你需要:

<?php
session_start();
if(isset($_SESSION['views']))
    { echo "Views: " . $_SESSION['views'];} 
    else 
    { echo "Views: NOT SET";}
?>

【讨论】:

  • 这会创建一个新会话,并且 $_SESSION['views'] 是主页面和子页面的不同数字。
  • 这是在服务器上的不同子域或路径上吗?如果 cookie 匹配,它应该使用相同的会话。
  • 我刚刚从两个文件中运行了 session_id() 并且它是相同的。但它仍然不会拉变量。
  • 您能否监控发送到服务器和从服务器发送的 HTTP 标头以确保在两个页面之间发送相同的会话 cookie?也许试试var_dump($_SESSION); 看看两者有何不同。如果实际上正在使用相同的会话,它们应该共享相同的数据。
  • 对于这个问题,您是第一个正确回答的问题,添加 session_start() 可以正常解决问题,但在我的情况下,发生了其他奇怪的事情,我将继续努力解决它。感谢您提供有用的建议。只有一个 cookie 并且 web 标头是相同的,但由于某种原因 php 不会获取会话变量,并且我的日志中没有错误。我将在本地 LAMP 服务器上尝试。
【解决方案2】:

您还需要在另一个 PHP 文件中启动会话 session_start(),也就是您通过 AJAX 调用的那个。

【讨论】:

    【解决方案3】:

    在使用付费网络托管服务的情况下,默认会话保存路径自动设置如下:

    http://php.net/session.save-path
    session.save_path = "/tmp/"
    

    您需要将根文件夹的静态路径放在那里。

    【讨论】:

    • 在哪里(默认会话保存路径)?我在哪里可以找到它?
    【解决方案4】:

    我今天在 IIS Server 2012 上运行 PHP 7 时遇到了我认为相同的问题。

    我已经添加:

    if(!isset($_SESSION)) 
    { 
        session_start(); 
    } 
    

    到每个 AJAX 文件的开头,但不断收到以下 PHP 通知:

    PHP Notice: A session had already been started - ignoring session_start()
    

    经过一番搜索,我找到了这个帖子,它为我指明了解决我遇到的问题的正确方向。希望以下信息可以帮助其他遇到相同问题的人。

    在检查 session.save_path 值是否已设置后,在我的情况下为 C:\Windows\Temp,我认为最好检查文件夹权限是否与我运行 IIS 的用户帐户的权限相匹配。

    在我的例子中,我为会话存储指定的目录(在 php.ini 中)没有分配给它与运行 IIS 站点的用户(安全权限)相同的用户(安全权限)。

    有趣的是,在我添加新用户权限之前不使用 AJAX 请求时会话运行良好。但是,直到我纠正了权限问题,AJAX 才开始进行会话。添加运行 IIS 的同一用户帐户可立即解决此问题。

    【讨论】:

      【解决方案5】:

      在您尝试通过 ajax 调用登录之前需要初始化会话。

      session_start();
      

      在您开始登录 ajax 调用的页面顶部初始化。

      这样 SESSIONID 将被创建并存储在浏览器 cookie 中。并在 ajax 调用期间与请求标头一起发送,如果您对同一域执行 ajax 请求

      对于连续的 ajax 调用,浏览器将使用最初创建并存储在浏览器 cookie 中的 SESSIONID,除非我们清除浏览器 cookie 或注销(或设置另一个 cookie)

      【讨论】:

        【解决方案6】:

        您正在尝试在 ajax 调用中使用应用程序中的现有会话数据。为此,请更改您调用 session_start 的方式,如下所示:

        // With ajax calls
        if (session_status()==1) {
            session_start(); 
        }
        

        当对需要现有会话数据的 php 脚本进行 ajax 调用时,在 session_status 之后使用 session_start。

        http://php.net/session_status

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-04-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-20
          • 2011-04-01
          • 2015-08-06
          相关资源
          最近更新 更多