我正在尝试实现一些代码,这些代码将允许我让一个子域与另一个子域通信,例如one.example.com
和two.example.com
。这两个站点能够共享cookie和会话数据,因为我已经将cookie设置为使用.example.com
。
当我通过标准HTTP访问任一站点时,我可以转储会话并查看预期的数据。但是,如果我使用jQuery $.ajax()
通过JavaScript执行此操作,则转储的会话数据为空。在这两种情况下,我都使用PHP来转储会话数据。
我尝试过以下解决方案,但没有成功(http://forum.kohanaframework.org/discussion/9895/problem-session-expired-with-ajax/p1)。我也在使用Kohana(3.3)的更新版本
我还试着在它们到达控制器时立即设置标题:
$this->response->headers('Access-Control-Allow-Origin', 'http://one.example.com');
$this->response->headers('Access-Control-Allow-Credentials', 'true');
$this->response->headers('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
然而,Chrome检查器仍然将Access-Control-Allow-Origin
显示为*
。
问题
我遇到的问题是由于我的Apache配置文件中的一个设置,它看起来像这样:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
为了解决我的特殊问题,我简单地删除/注释掉了上面的代码,因为它覆盖了我从PHP发送的头。
当时我实现的解决方案非常简单。在下面的示例中,我们将假设我正在从one.example.com
(主网站)呼叫two.example.com
(子网站)。
Kohana/PHP
在我的PHP中,我设置了以下标题,我选择在我的父控制器中这样做。如果你愿意,你可以创建自己的Cors类或助手。基本上,您不希望在整个项目中重复此代码数百次。
$this->response->headers('Access-Control-Allow-Origin', 'http://one.example.com');
$this->response->headers('Access-Control-Allow-Credentials', 'true');
$this->response->headers('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
JavaScript/jQuery
在我的$.ajax()
请求中,我必须确保将xhrFields.withCredentials
属性设置为true
。
$.ajax({
url: 'two.example.com',
xhrFields: {
withCredentials: true
}
});
或者我可以为所有ajax请求全局设置它,比如:
$(document).ajaxSend(function (event, xhr, settings) {
settings.xhrFields = {
withCredentials: true
};
});
有关更多信息,请查看$.ajax
文档:http://api.jquery.com/jQuery.ajax/
进一步阅读
有关更多信息,请查看以下资源:
- https://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
- http://enable-cors.org/