views:

607

answers:

5

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.url.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.website.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';
}
?>
+5  A: 

"Permission denied" sounds suspiciously as if you're having same origin policy issues.

chaos
Yeah this was kinda it - see comment at bottom. Thanks for the help!
hfidgen
+2  A: 

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.

Jim Fiorato
Everything was same domain, as far as I was concerned, and a lot of the urls were even relative but it didn't like http://www.mysite.com and http://mysite.com
hfidgen
+2  A: 

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.

vava
I think you're confusing cross-site scripting with cross-domain XMLHTTP requests. http://en.wikipedia.org/wiki/Cross-site_scripting
Jim Fiorato
Thanks, I'm not so good with terminology.
vava
How can i distinguish between a url with www and one without in javascript? Is there some way of telling the ajax code that either is fine?
hfidgen
Like I said in second paragraph, you could set document.domain = "example.com"; in your javascript prior to making any AJAX calls. It'll help to negate difference between "www.example.com" and "example.com"
vava
ahhh i see - thanks a lot!
hfidgen
XMLHttpRequest requires special permissions for cross domain requests, not AJAX. AJAX is just a programming functionality, and can be cross domain with some implementations. Trivial.. I know.
bucabay
As I already said, I'm not so good with terminology :)
vava
+2  A: 

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:

http://json-proxy.jgate.de/

Here is another specifically set up to consume XML resources and respond with JSON.

http://jsonproxy.appspot.com/

bucabay
Hiya, yeah this appears to be it! It works fine on http://www.mysite.com but when i'm using http://mysite.com it breaks at the "back" link stage. I guess I now need to put some php in place to format the $home_url depending on what the user has in the browser url bar.
hfidgen
If you use relative URLs then you don't need to know what is in the browser URL bar. You can also get the host from window.location.host. Or the full URL, window.location.href
bucabay
A: 
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 :)

hfidgen