Sorry, this looks longer than it probably is but I thought I should include all the information!
I'm using a simple Ajax script to dynamically bring content into a <div> on a page. The first request to load some new content into the div works fine, but if I've got an Ajax "back" link within the content which has just loaded, it seems to throw an error.
Even stranger, it works on my office network, but it fails If I'm on a home or VPN network. If it fails, this error pops up in the JavaScript debugger:
Line: 12
Char: 11
Error: Permission Denied
Code: 0
URL: http://www.example.com/about.php
The code really isn't that complex, it's just a slightly hacked around version of the stuff on the W3 website, but the fact that the return call is "denied" is confusing me. Would it be something within the server IIS configuration to stop scripting attacks? (Random thought?)
Any help appreciated ;)
First - the Ajax script
var myHttpRequest = false;
if(window.XMLHttpRequest)
myHttpRequest = new XMLHttpRequest();
else if(window.ActiveXObject)
myHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
function loadContent(source, content)
{
if(myHttpRequest)
{
var data = document.getElementById(content);
myHttpRequest.open("GET",source);
data.innerHTML = '<div class=\"loading_image\"><img src=\"images/loading.gif\" width=\"54px\" height=\"55px\" alt="loading" /></div>';
myHttpRequest.onreadystatechange = function()
{
if(myHttpRequest.readyState==4)
data.innerHTML = myHttpRequest.responseText;
$('#col2_2_content').supersleight();
}
myHttpRequest.send(null);
}
}
Then this is a truncated example of the page which calls the Ajax content and has the col2_2_content Div where everything gets inserted. The file ajax.js
is referenced in the head section.
<div id="col2_2_content">
<div class="mugshot_container">
<img src="images/mugshot_dh.jpg" onClick="loadContent('about/dh.php?ajax=yes', 'col2_2_content');"/>
</div>
</div>
And this is the code from about/dh.php
which is inserted via Ajax, along with the PHP formatting to decide what should be returned. (It's designed to be called directly too - in which case it gets a header/footer wrapped around).
<?php
$home_url = "http://www.example.com/url/";
$content = "
<p>Some Text</p>
<p><a onClick=\"loadContent('$home_url/about/about-main.php?ajax=yes', 'col2_2_content');\">Back</a></p>
";
if (isset($_REQUEST['ajax']) ) {
echo $content;
} else {
include_once 'about-header.php';
echo $content;
include_once 'about-footer.php';
}
?>
"Permission denied" sounds suspiciously as if you're having same origin policy issues.
Is the $home_url
located on the same domain as the page that is making the XMLHTTP request?
The permission denied error is almost always because of an attempt to request content across domains or security zones... (http://msdn.microsoft.com/en-us/library/ms537505%28VS.85%29.aspx#xdomain) Especially since you're seeing it over the VPN and not in the office, this sounds like it could be the issue.
I'd fire up Firebug or some other debugging tool that allows you to see what the request is.
You got yourself in cross-domain request situation. AJAX requests basically can be made only to the server that served the page. So if your script page is loaded from http://website.com/url
, you can make any call to http://website.com/
but any call to http://url.com
would fail.
Having said that, it is possible to call http://s1.example.com
from http://s2.example.com
if you run document.domain = "example.com"
.
But if you really need to access data across domains, there's few ways to do that. Simplest one I know is to use <script>
tag to do the query. You can edit your document to add <script>
tag with any src
you like and browser will go there and fetch the script for you. So if you control http://url.com
, you can just make it create a javascript instead of HTML page and this script would be loaded and executed. This method is used to make JSONP work.
Cross-site scripting might work without security issues in the local network because IE doesn't put that much restrictions in that case. I doubt though it will work in any other browser even in your LAN.
Given all the answers already posted. I'd suggest you use relative URLs. XMLHttpRequest can go cross domain in latest browsers I believe. The specifications for this was released a while ago by W3C.
I believe this is it: http://www.w3.org/TR/access-control/
You can also use dynamic script tags if you want to go cross domain. That seems to be the most popular. Usually, this is implemented with the javascript page writing a callback, with JSON as the parameter.
There are numerous other ways to enable cross domain http in the browser, but they all involve prior setup, unless you use a proxy. You can actually use a proxy that responds with Javascript, so the proxy can also be on a remote domain.
I have an example here:
Here is another specifically set up to consume XML resources and respond with JSON.
if ($_SERVER['HTTP_HOST'] == "mysite.com") {
$home_url = "http://mysite.com/testing/rebrand/";
} else {
$home_url = "http://www.mysite.com/testing/rebrand/";
}
Can't post this in a comment, so putting it here ;)
This did the trick - I added this in config.php to differentiate between the domains. Everything now works A-OK. Thanks guys :)
Note -- Note
do not use "http://www.domain.xxx" or "http://localhost/" or "IP >> 127.0.0.1" for URL in ajax. only use path(directory) and page name without address.
false state:
var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'http://www.example.com/dir1/dir2/page.php', true);
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);
true state:
var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST','dir1/dir2/page.php', true); // <<--- note
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);
function createAjax()
{
var ajaxHttp = null;
try
{
if(typeof ActiveXObject == 'function')
ajaxHttp = new ActiveXObject("Microsoft.XMLHTTP");
else
if(window.XMLHttpRequest)
ajaxHttp = new XMLHttpRequest();
}
catch(e)
{
alert(e.message);
return null;
}
//-------------
return ajaxHttp;
};