AJAX 调用在没有明显原因的情况下破坏会话

Posted

技术标签:

【中文标题】AJAX 调用在没有明显原因的情况下破坏会话【英文标题】:AJAX call destroys session wiht no apparent reason 【发布时间】:2012-11-10 04:36:00 【问题描述】:

我知道这看起来像一个平庸的问题,但请阅读整篇文章,我被这个难住了。

我的一个页面上有一个 AJAX 调用,它是一个动态消息传递系统:

function validateMessage()

  var recipient = document.getElementById("send_to").value;
  var subject = document.getElementById("popup_subject").value;
  var message = document.getElementById("popup_message").value;

  var parameters="message="+message+"&recipient="+recipient+"&subject="+subject;

   if (window.XMLHttpRequest)
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
   
   else
   // code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
   

   xmlhttp.onreadystatechange=function()
  
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    
        document.getElementById("error_mess").innerhtml = xmlhttp.responseText;
    
  

  xmlhttp.open("POST","include/send_message.php",false);
  xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
  xmlhttp.send(parameters);

  

它被实现为同步是有原因的,这不是这里的问题。我尝试切换到异步,但问题仍然存在。

这是 send_message.php 文件,它只是抓取 POST 变量并将它们保存到数据库中:

<?php
session_start();
include('db.php');
dbConnect();

$message=$_POST['message'];
$subject=$_POST['subject'];
$recipient=$_POST['recipient'];

$result=mysql_query("select * from korisnici where username='$recipient' ") or die(mysql_error());
$row=mysql_fetch_array($result);
$num=mysql_num_rows($result);

if($recipient=="Poruka za..." || $subject=="Naslov..." || $message=="Poruka" || $recipient=="" || $subject=="" || $message=="")
    echo "<p style='color:red;'>Morate popuniti sva polja.</p>";
elseif($num==0)
    echo "<p style='color:red;'>Korisnik ne postoji.</p>";
else
    $prima=$row['id_user'];
    $salje=$_SESSION['id_user'];
    mysql_query("insert into poruke (salje, prima, naslov, poruka)
        values ('$salje', '$prima', '$subject', '$message') ") or die(mysql_error());
    echo "<p style='color:green;'>Poruka uspješno poslata!</p>";


?>

但是,当我尝试保存 $_SESSION['id_user'] 变量(作为发件人)时,我发现了一个问题 - 每次运行此 AJAX 调用时会话都会被破坏!所以在session_start() 之后执行print_r($_SESSION) 会打印一个空数组。

会话在原始页面本身上处于活动状态,刷新该页面可保持会话处于活动状态。只有当我单击按钮进行 AJAX 调用时,会话才会消失。有人能发现问题吗?

【问题讨论】:

我认为问题不在于可见代码。这里不应该破坏会话变量。 我也很确定。那么,这可能是什么原因呢?我以前从来没有发生过。除了我发布的内容之外,实际上没有涉及任何代码。原始页面(调用的来源)甚至没有提到任何会话内容,除了页面开头的 session_start()。 我以前见过这样的问题,问题是PHP服务器配置错误。由于会话使用 cookie,我也看到了与浏览器打交道的类似问题。您可能想下载并尝试使用不同的浏览器以确保安全。其他地方的某些代码也可能有问题。不能从我在这里看到的真正说出来。 其他浏览器也会发生同样的事情。至于服务器,它在我多年来一直用于开发的共享服务器上,从未遇到过这个问题。我想我会尽量放弃他们的支持,我完全没有想法。 在我看到的错误配置服务器的情况下,任何使用会话的 PHP 程序都会间歇性出现问题。我建议你制作一个使用会话的超级简单程序,然后一遍又一遍地刷新它,看看会话是否会中断。 【参考方案1】:

这是我的托管服务提供商的技术支持团队提供给我的解决方案:

在 /home/username/public_html 中设置 suhosin.session.encrypt=Off

在 .htaccess 中设置 suPHP_ConfigPath /home/username/public_html。

就是这样,现在可以使用了。目前没有时间调查这些设置,但我希望这会对处于相同情况的人有所帮助。

【讨论】:

我也面临同样的问题。但我无法像你说的那样修复它。我是否在我的应用所在文件夹的 .htaccess 中使用这两行?我的意思是Set suhosin.session.encrypt = OffSet suPHP_ConfigPath /folder/...。我尝试了第一个设置并给了我服务器错误,可能是语法有问题? 第二行进入.htaccess。至于第一个,我真的不记得了,但我相信我是通过 WHM 在我的专用服务器上设置的。我确定也可以通过 SSH 设置,但是不知道要编辑哪个文件。【参考方案2】:

请检查表单的开始和结束,非常重要的是,请检查您是否将按钮设置为 onclick 并返回 false。如果没有,它将重定向并且没有会话。

【讨论】:

以上是关于AJAX 调用在没有明显原因的情况下破坏会话的主要内容,如果未能解决你的问题,请参考以下文章

MVC 身份验证超时/会话 cookie 删除后的 Ajax 请求

在没有ajax调用的情况下使用带有@HTML.BeginForm的formdata append

如何在没有 ajax 调用的情况下在 window.location 中传递一个数组

laravel 4持续数据正在进行 - jquery ajax提交

laravel 4持续数据正在进行 - jquery ajax提交

Grails,在 AJAX 调用中处理会话超时