• Visitors can check out the Forum FAQ by clicking this link. You have to register before you can post: click the REGISTER link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below. View our Forum Privacy Policy.
  • Want to receive the latest contracting news and advice straight to your inbox? Sign up to the ContractorUK newsletter here. Every sign up will also be entered into a draw to WIN £100 Amazon vouchers!

Ajax same origin policy

Collapse
X
  •  
  • Filter
  • Time
  • Show
Clear All
new posts

    Ajax same origin policy

    Just trying to get my head round the finer points of the browser restrictions on making an XMLHttpRequest to a different domain - the same origin policy.

    I've been told that this will not be a problem as long as the javascript files are loaded from the domain which will be receiving the call. i.e.

    www.domain1.com hosts the file ajax.js which contains all Ajax functions

    www.domain2.com/default.html includes the file www.domain1.com/ajax.js

    I can't seem to find any clear reference to this set up being any more valid than if ajax.js was hosted on www.domain2.com (which would fail if it made a call to www.domain1.com).

    Anyone happen to know if the host of the javascript source file makes any difference to the policy restrictions? (Before I launch into a load of tests.)

    #2
    Nope - doesn't work

    You can freely load a script from another domain, but the same-origin policy applies to the domain of the document, not the domain of the script.

    I've chucked together a quick demo. This loads:
    • a script from testpleasdelete.com which creates a button that does an XHR to testpleasedelete.com;
    • a script from nickfitz.co.uk which creates two buttons, one of which does an XHR to testpleasedelete.com, and one which does an XHR to nickfitz.co.uk.


    Try all three buttons and you'll see that the last one, where the script from nickfitz.co.uk attempts to send a request thereto, throws an exception.

    (I've wrapped up the responses and the exception in alerts, to make it easy to see what's happening. Also, I've only tested in FF and Safari, but it should work in Opera, Konqueror and IE7 - though not in IE6, as I couldn't be bothered to do the jiggery-pokery calling ActiveXObject instead of the XMLHttpRequest constructor.)

    EDIT: FWIW, here's the nickfitz.co.uk version of the script:

    Code:
    var test = test || {};
    
    test.nickfitz = {
        domain: "www.nickfitz.co.uk",
        scriptSourceURL:   "http://",
        documentSourceURL: "http://",
        xmlPath:           "/temp/test.xml",
        container:         document.getElementById("tests"),
        init: function() {
            this.scriptSourceURL += this.domain +  this.xmlPath;
            this.documentSourceURL += self.location.host + this.xmlPath;
            this.addTest(true);
            this.addTest(false);
        },
        addTest: function(useDocumentDomain) {
            var p = this.container.appendChild(document.createElement("p"));
            var button = p.appendChild(document.createElement("button"));
            button.appendChild(document.createTextNode(this.domain + " accessing " + (useDocumentDomain ? self.location.host : this.domain)));
           button.onclick = this.makeScopedHandler(this, useDocumentDomain ? this.documentSourceURL : this.scriptSourceURL);
        },
        makeScopedHandler: function(that, url) {
            return function() {
                return (function() {
                    var xhr = new XMLHttpRequest();
                    xhr.onreadystatechange = function() {
                        if (xhr.readyState == 4) {
                            alert(xhr.responseText);
                        }
                    }
                    try {
                        xhr.open("GET", url, true);
                        xhr.send();
                    } catch(e) {
                        alert(e);
                    }
                }).apply(that);
            };
        }
    };
    
    
    test.nickfitz.init();
    Last edited by NickFitz; 9 September 2008, 20:16.

    Comment


      #3
      Nice one NF. It did seem unlikely, but I was told with such confidence that I couldn't be sure.

      Sorry to make you do the work (but I suspect you secretly enjoy enjoy it anyway).

      Back to JSON inside script tags I think, which is what all the big APIs seems to use.

      Comment


        #4
        Originally posted by NickFitz View Post

        (I've wrapped up the responses and the exception in alerts, to make it easy to see what's happening. Also, I've only tested in FF and Safari, but it should work in Opera, Konqueror and IE7 - though not in IE6, as I couldn't be bothered to do the jiggery-pokery calling ActiveXObject instead of the XMLHttpRequest constructor.)
        For reference:

        Code:
        /*@cc_on @if (@_win32 && @_jscript_version >= 5) if (!window.XMLHttpRequest)
        window.XMLHttpRequest = function() { return new ActiveXObject('Microsoft.XMLHTTP') }
        @end @*/

        Comment


          #5
          Originally posted by King Cnvt View Post
          For reference:

          Code:
          /*@cc_on @if (@_win32 && @_jscript_version >= 5) if (!window.XMLHttpRequest)
          window.XMLHttpRequest = function() { return new ActiveXObject('Microsoft.XMLHTTP') }
          @end @*/
          I know, but this was some quick and dirty code.

          More importantly, MS's XML team state that you should not use the Microsoft.XMLHTTP ProgID, as this a legacy ProgID, and is not guaranteed to be supported (and apparently isn't supported by MSXML2 version 6, in Vista but also to be encountered in some XP installations). You should always use an MSXML2.* ProgID when using the old ActiveXObject method of instantiation.

          So the best way of dealing with non-IE7 Windows systems would be:

          Code:
          if (window.XMLHttpRequest) {
              // use the XMLHttpRequest constructor
          } else {
              if (window.ActiveXObject) {
                  // whole bunch of garbage trying to get an instantiation by try-catching a lot for different versions of the MSXML DLL with various versions of MSXML2 ProgIDs, eventually leading to...
              } else {
                  // XHR not supported - please don't shit on the user here
              }
          }
          All the MS proprietary conditional stuff (/*@cc blah-di-blah */ and so forth) is irrelevant, as one can use standard JS techniques for detecting the capabilities of the runtime system, and falling back gracefully.

          As such Ajaxey gubbins should only be implemented as a form of progressive enhancement, "falling back" in this case means "behaving normally", and if XHR is supported, then the application behaves "normally, but better".

          There are also certain techniques related to the fact that, in JavaScript, functions are objects, and object properties (including methods, because they are just properties, being functions, which are objects) can be dynamically modified, which allow for a number of optimisations - but the margins of this post are too small to contain them

          Comment

          Working...
          X