Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't setting document.domain work to allow AJAX requests to a parent domain?

I have two files, 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>

and domain.com/test3.php:

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

In this case domain.com/test2.php outputs var1: 1 , var2: 2 as one would expect, but let's now say I want to make a test2.php in a subdomain. To stop problems with cross-domain scripting, I would add this extra line to the start of sub.domain.com/test2.php:

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

This extra line stops the cross-domain error from showing up, but now the file no longer outputs var1: 1 , var2: 2. Why is this and how can I fix this?

like image 422
Edward Stumperd Avatar asked Mar 22 '13 05:03

Edward Stumperd


1 Answers

The document.domain mechanism is intended for allowing client-side communication between frames, rather than client-to-server communication. If you have one frame containing a page from example.com and another frame containing a page from foo.example.com then the two cannot access each other's DOM unless the latter sets document.domain to example.com as you showed in your example.

The modern preferred mechanism for cross-domain AJAX requests is Cross-Origin Resource Sharing, or "CORS". This mechanism involves having the target resource return a special HTTP response header that indicates that cross-domain requests are allowed. In your scenario you'd make your test3.php return the following HTTP response header:

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

In PHP you'd do this as follows:

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

You can also set this header value to just * in order to allow cross-domain requests from any origin, but be aware that this will allow requests from sites you don't control.

Requests from client-side JavaScript libraries often also include the additional header X-Requested-With that is not in the standard set allowed by CORS, so it may be necessary to explicitly allow this header via an additional response header:

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

CORS is only supported in modern browsers. For older browsers the common convention is to use JSON-P, which is a trick exploiting the fact that a page on one server is able to load and execute a script file from another server. This technique requires that the target resource be a valid JavaScript program that calls a function in the page, so it's not as elegant and seamless as CORS but it should work in any browser that supports JavaScript.

like image 106
Martin Atkins Avatar answered Oct 07 '22 16:10

Martin Atkins