如何使用子域和AJAX使PHP会话正常工作?

5
我正在开发一个使用子域名、会话和Ajax的PHP项目。但不幸的是,我无法让它工作!我尝试解释一下:
假设我在这个域名下:app.mysite.com/index.php 在这个域名下,我有一个表单,该表单执行一个Ajax请求到mysite.com/functions/execute.php(没有任何子域名)
在execute.php的第一行,我有一个require_once,其中包括一个helper.php文件。在这个文件中,我写了以下内容:
ini_set('session.cookie_domain',  '.mysite.com');
session_set_cookie_params(0, '/', '.mysite.com');
session_start();

所有列出的PHP文件也包括helper.php。
例如,如果我运行:
echo $_SESSION["myValue"];

app.mysite.com/index.php 或其他子域名(如 auth.mysite.com)中,我会得到值:"test"。但如果我在 execute.php 中运行相同的代码,并通过 Ajax 返回该值,则会得到未定义索引错误!我做错了什么?

https://dev59.com/0GUq5IYBdhLWcg3wTuqi - Bogdan Burym
这些可能是相关的。[1](https://dev59.com/lWox5IYBdhLWcg3whUmm),[2](https://dev59.com/r3NA5IYBdhLWcg3wKam3),[3](https://dev59.com/zXRB5IYBdhLWcg3wXmNI)仅用“possible”因为这些都是3年以上的旧问题,所以它们可能不再适用。如果可以,请在问题中添加您的PHP版本,并且如果其中一个解决了您的问题,请回答自己的问题或去留言说哪个解决方案仍然有效。 - user5051310
谢谢回答,但不幸的是我无法使用AJAX获取$_SESSION值。如果我在浏览器中打开AJAX请求的URL,我可以看到$_SESSION的值。只有使用AJAX时它不起作用! - jNewbie
3个回答

3

我已经想出如何使其工作。默认情况下,Ajax Post方法不会发送凭据头,因此我们需要手动启用:

$.ajax({
    method   : "POST",
    url      : "https://example.com/functions/execute.php", 
    data     : myData,
    xhrFields: { 
        withCredentials: true
    }
}).done(function(result) {
    alert("success"));
});

execute.php 中,您需要放置以下内容:
ini_set('session.cookie_domain',  '.example.com');
session_set_cookie_params(0, '/', '.example.com');
session_start();
header('Access-Control-Allow-Credentials: true');

如果您在子域名上发起请求,还需要在 example.php 中加入以下内容:

header('Access-Control-Allow-Origin: http://app.example.com');

1

1
如果您的项目是基于Web的应用程序,您可以通过一个简单的技巧在所有域中轻松设置cookie/session。我相信这适用于cookie,但从未尝试过会话。让我们来模仿Google的做法。创建一个PHP文件,在所有3个域上设置cookie。然后在主题将被设置的域上创建一个HTML文件,该文件将加载在其他2个域上设置cookie的PHP文件。例如:
<html>
   <head></head>
   <body>
      <p>Please wait.....</p>
      <img src="http://domain2.com/setcookie.php?theme=whateveryourthemehere" />
      <img src="http://domain3.com/setcookie.php?theme=whateveryourthemehere" />
   </body>
</html>

保持那些元素隐藏,这样如果页面对用户可见,就不会显示任何破损的图片。然后在标签上添加一个onload回调函数。文档只有在图片完全加载时才会加载,也就是在另外两个域名上设置cookie时。Onload回调函数:
<head>
   <script>
   function loadComplete(){
      window.location="http://domain1.com";//URL of domain1
   }
   </script>
</head>
<body onload="loadComplete()">

我们可以使用类似这样的PHP文件(setcookie.php)在其他域上设置Cookies:

<?php
if(isset($_GET['theme'])){
   setcookie("theme", $_GET['theme'], time()+3600);
}
?>

现在,cookie已在这三个域上设置:)通过Web应用程序,您知道如何检索cookie :)

当然,根据您的要求,您可能需要调整此代码。但是,这肯定会给您一个进一步的想法。

希望这可以帮助您


谢谢您的回答,但是对我没有帮助。我的目标是在子域和根域之间使用相同的会话来进行Ajax通信,但我已经找到了解决方法! - jNewbie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接