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

Posted

技术标签:

【中文标题】如何使用子域和 AJAX 使 PHP 会话工作?【英文标题】:How make PHP session work using subdomain and AJAX? 【发布时间】:2017-02-05 20:22:33 【问题描述】:

我在一个使用子域、会话和 Ajax 的 php 项目中工作。但不幸的是我不能让它工作!我会尽力解释:

假设我在这个域:app.mysite.com/index.php

在这个域中,我有一个表单可以向 mysite.com/functions/execute.php(没有任何子域)执行 Ajax 请求

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,我会得到值:"测试”。 但是如果我在 execute.php 上运行相同的代码,并通过 Ajax 返回值,我将得到未定义的索引!

我做错了什么?

【问题讨论】:

***.com/questions/14611545/… 这些可能是相关的。 1, 2, 3 只有“可能”因为这些都是 3 岁以上的问题,所以它们可能不再起作用。如果愿意,请将您的 php 版本添加到问题中,如果其中一个解决了您的问题,请回答您自己的问题或对那些说哪种解决方案仍然不错的人发表评论。 感谢您的回答,但不幸的是,我无法使用 AJAX 获取 $_SESSION 值。如果我打开 AJAX 上请求的 URL,在我的 Web 浏览器中我可以看到 $_SESSION 值。只使用不起作用的 AJAX! 【参考方案1】:

我已经弄清楚如何进行这项工作。 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');

【讨论】:

【参考方案2】:

如果您的项目是基于 Web 的应用程序,您可以通过一个简单的技巧轻松地在所有域中设置 cookie/会话。确信这适用于 cookie,但从未尝试过会话。让我们做谷歌正在做的事情。创建一个 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>

隐藏那些img元素,这样如果页面对用户可见,它就不会在前端显示任何损坏的图像。然后在body标签上添加一个onload回调。仅当图像完全加载时,即在其他 2 个域上设置 cookie 时,文档才会加载。加载回调:

<head>
   <script>
   function loadComplete()
      window.location="http://domain1.com";//URL of domain1
   
   </script>
</head>
<body onload="loadComplete()">

我们使用这样的 PHP 文件(setcookie.php)在其他域上设置 cookie ) :

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

?>

现在 cookie 设置在三个域上:) 并且使用 Web 应用程序您知道如何检索 cookie:)

当然,您可能需要根据您的要求修改此代码。但这肯定会给你一个继续的想法

希望对你有帮助

【讨论】:

感谢您的回答,但没有帮助我。我试图做的是使用 Ajax 在子域和根域之间使用相同的会话,但我已经想出了如何做到这一点!【参考方案3】:

请参考此链接。希望对你有帮助。

Setting a cookie on a subdomain from an ajax request

I do not see SESSION vars when calling subdomain script with Jquery (ajax)

谢谢!

【讨论】:

以上是关于如何使用子域和 AJAX 使 PHP 会话工作?的主要内容,如果未能解决你的问题,请参考以下文章

域和子域的 PHP 会话

使子域读取父域会话

如何防止 Ajax 调用使会话保持活动状态?

Laravel PHP 获取引用

无法使用 Laravel 4 与子域共享会话

使用 Express 和 Node,如何跨子域/主机头维护会话