一尘不染

为什么设置document.domain不能允许AJAX请求到父域?

ajax

我有两个文件domain.com/test2.php:

<div id="testDiv"></div>

<script src="http://domain.com/packages/jquery.js"></script>
<script>$("#testDiv").load("http://domain.com/test3.php", {var1:1, var2:2});</script>

和domain.com/test3.php:

<b>var1: <?php echo $var1; ?> , var2: <?php echo $var2; ?></b>

在这种情况下,domain.com/test2.php的输出 var1: 1 , var2: 2
与您期望的一样,但是现在让我们说我想在一个子域中创建一个test2.php。为了阻止跨域脚本编写问题,我将在sub.domain.com/test2.php的开头添加以下额外的行:

<script>document.domain = "domain.com";</script>

此额外的行阻止了跨域错误的显示,但是现在该文件不再输出 var1: 1 , var2: 2 。为什么会这样,我该如何解决?


阅读 229

收藏
2020-07-26

共1个答案

一尘不染

document.domain机制旨在允许帧之间进行客户端通信,而不是客户端到服务器的通信。如果从包含页面的一帧example.com,并从包含页面另一个框架foo.example.com则二者不能互相访问对方的DOM,除非后者套document.domainexample.com你在你的例子显示。

跨域AJAX请求的现代首选机制是“ 跨域资源共享 ”或“
CORS”。此机制涉及使目标资源返回一个特殊的HTTP响应标头,该标头指示允许跨域请求。在您的方案中,您将test3.php返回以下HTTP响应标头:

Access-Control-Allow-Origin: sub.domain.com

在PHP中,您可以按照以下步骤进行操作:

header("Access-Control-Allow-Origin: sub.domain.com");

您也可以将此标头值设置为仅仅*是为了允许来自 任何 来源的跨域请求,但请注意,这将允许来自不受您控制的网站的请求。

来自客户端JavaScript库的请求通常还包含X-Requested- With不在CORS允许的标准集中的其他标头,因此可能有必要通过附加的响应标头显式允许此标头:

Access-Control-Allow-Headers: X-Requested-With

仅现代浏览器支持CORS。对于较旧的浏览器,通常的约定是使用JSON-P,这是一种技巧,它利用了一个服务器上的页面能够从另一台服务器加载并执行脚本文件这一事实。此技术要求目标资源是一个有效的JavaScript程序,该程序在页面中调用一个函数,因此它不像CORS那样优雅和无缝,但它应在任何支持JavaScript的浏览器中都可以工作。

2020-07-26