繁体   English   中英

如何使用AJAX加载外部javascript文件并知道加载失败?

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

我编写了一个函数,该函数将URL字符串数组作为第一个参数,并尝试使用它们来加载外部脚本。 这样一来,当一个镜像发生故障时,我就可以链接多个源。

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();
}

问题在于,烦人的CORS正在破坏此设计:

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.

我该如何克服? 为什么通过src加载脚本是可以的,但是ajax请求会引发错误?

与其尝试通过XHR查询获取js文件,不如通过创建一个新的<script>元素并将其src=属性设置为您要加载的文件来通过DOM加载它? 由于是DOM,因此跨域加载是合法的。

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);
}

(不确定您对name参数/变量的处理方式,因此我将其保留下来。您可能应该处理要与name一起使用的任何逻辑。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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