简体   繁体   中英

How can I load external javascript files using AJAX and know that loading has failed?

I have written a function that takes array of URL strings as first argument and tries to use them to load external script. This allows me to link multiple sources in case one mirror was down.

function loadScript(scripts, name, index) {
  //Convert single string to array - not effective but easy
  if(!(scripts instanceof Array))
    scripts = [scripts];
  //Use first script src if no name is defined
  if(name==null) {
    name = scripts[0];
  }
  //Default index is 0
  if(index==null)
    index = 0;
  //In case wrong index was provided
  if(index>=scripts.length)
    throw new Error("Aray index out of bounds.");

  //Create request
  var req = new XMLHttpRequest();
  req.open("GET", scripts[index]);
  //Execute response text on success 
  req.onload = function() {
    scriptFromString(this.responseText);
  }
  //Iterate on error
  req.onerror = function() {
    if(index+1<scripts.length) {
      loadScript(scripts, name, index);
    }
    else {
      throw new Error("All sources failed for '"+name+"'.");
    }
  }
  req.send();
}

The problem is that the annoying CORS is breaking down this design:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://[...].js. This can be fixed by moving the resource to the same domain or enabling CORS.

How can I overcome this? Why loading a script by src is ok, but ajax request throws errors?

Instead of trying to get the js file with an XHR query, why not load it through the DOM by creating a new <script> element and setting its src= attribute to the file you're trying to load? Since it's DOM, loading from across domains is legal.

function loadScript(scripts, name, index) {

    //Convert single string to array - not effective but easy
    if (!(scripts instanceof Array)) scripts = [scripts];

    //Use first script src if no name is defined
    if (!name) name = scripts[0];

    //Default index is 0
    if (!index) index = 0;

    //In case wrong index was provided
    if (index >= scripts.length) throw "Array index out of bounds.";

    //Create request
    var include = document.createElement('script');
    with(include) {
        type = "text/javascript";
        src = scripts[index];
        onload = function () {
            return;
        };
        onerror = function () {
            if (++index < scripts.length) {
                loadScript(scripts, name, index);
            } else {
                throw "All sources failed for '" + name + "'.";
            }
        };
    }
    document.head.appendChild(include);
}

(Not sure what you're doing with the name argument / variable, so I left it alone. You might ought to work on whatever logic you intended to employ with name .)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM