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

时间:2014-11-19 12:49:58

标签: javascript ajax cors

我编写了一个函数,它将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请求会抛出错误?

1 个答案:

答案 0 :(得分:0)

不是尝试使用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打算使用的任何逻辑。)

相关问题