0

为了加载一些 geojson 数据,我需要在外部域上获取脚本,比如http://www.stat.ucla.edu/~jeroen/files/la_county_simplified.min.json. 我无法控制这个脚本的内容;我只知道 url,以及我感兴趣的脚本中定义的对象的名称。脚本的虚拟版本如下所示:

var my_data = {"foo" : 123, "bar" : 456}

现在在我的应用程序中,我想my_data从它的 URL 动态加载对象。因为是跨域的,所以不能用ajax。也不完全jsonp是,因为我的脚本定义了一个对象,而不是一个函数。一种方法是将其简单地作为 a 插入<script>当前文档的头部。但是,我想避免可能的副作用。

什么是更清洁的解决方案?我正在考虑创建一个<iframe>然后在 iframe 中插入<script>标签,并在 iframe 加载后提取对象。但是我不确定这是一个可靠的方法,可以跨浏览器工作(特别是绑定回调以在 iframe 中加载脚本后提取对象)。

是否有一些库或标准解决方案可以在干净的页面中加载脚本,并将特定对象的副本提取到主页?我已经依赖于 jQuery,所以这很好。

4

4 回答 4

2

如果你打算做这个纯客户端并且不能格式化你的数据,你可以使用 JSONP和一个 twist。我们没有修改数据以适应回调,而是重新调整加载器以适应数据。

我们听onload脚本的。当脚本加载时,变量现在应该在全局范围内,我们执行回调,将全局变量传递给我们的回调。

//your script loader
function loadData(url,varName,callback){

  var script = document.createElement('script');
  document.getElementsByTagName('head')[0].appendChild(script);

  //when the script loads, we pass in `window.my_data`
  script.onload = function(){
    callback.call(this,window[varName]);
  };
  script.src = url;

}

//using it
loadData('http://example.com/somefile.js','my_data',function(data){
  //executes when script is loaded, where data is `my_data`
});

这种方法的缺点是每次加载脚本时,都会将其加载到全局范围内,并且可能会发生冲突。

于 2013-04-22T23:52:55.103 回答
0

没有其他方法可以解决它,因为您必须击败相同的来源策略,您必须在新的脚本标签中加载脚本,JSONP 也可以这种方式工作,但 jquery 会为您隐藏它。

无论是那个还是站点都有 cors 标头,如果站点没有 cors 标头,您可以在这里加载数据(不使用 jsonp,因为它不是 jsonp 格式):

function loadJS(url){
  var s=document.createElement("script");
  s.src=url;
  $(s).on("load",function(){
    console.log("var abvailable");//do something with the variable here
    $(s).remove();
  });
  document.head.appendChild(s);
}
loadJS("http://code.jquery.com/jquery-1.9.1.min.js");
于 2013-04-23T00:08:16.043 回答
0

iframe 方法应该可以正常工作:

  • 创建一个 iframe
  • 注入指向文件的脚本标签
  • 在脚本加载时,检索对象

我能想到的唯一跨浏览器问题是您需要在现代浏览器中使用 addEventListener 并在旧 IE 中使用 attachEvent 。

这是将 iframe 用作沙箱的标准用法 - 如果我理解正确,您担心可能与全局变量名称发生冲突。

[更新] 为了解决您的一些评论,这里是一些跨浏​​览器代码:

添加事件监听器:

function addEvent(element,event,fn,capture){
// capture defaults to false if omitted
if (element.addEventListener) {element.addEventListener(event,fn,(capture||false));}
// else for old IE
else {element.attachEvent('on'+event,fn);}
};

要访问 iframe 文档:

function iframeDocument(ifr){
var doc=ifr.contentWindow||ifr.contentDocument;
if (doc.document) doc=doc.document;
return doc;
};

如果您使用 jQuery,.on("load")并且$(ifr).contents()会处理这些跨浏览器兼容性问题。

于 2013-04-23T00:20:09.007 回答
-1

JSON-P 是一种从远程域加载 JavaScript 的方式。

JavaScript 的返回格式是以响应数据为参数调用函数。

someGlobalFunctionName({/* your response data */});

function someGlobalFunctionName(data) { /* do something with data */ }

由于数据包含在对象中并传递给函数,因此除了全局函数本身之外,没有全局泄漏,这是不可避免的。

更多信息:http: //json-p.org/

于 2013-04-22T23:50:34.303 回答