传递给外部JavaScript的JSON对象

10

我在研究FireBug Lite时发现他们使用了一个非常棒的技巧,在外部脚本文件中传递选项:

<script type="text/javascript" src="https://getfirebug.com/firebug-lite.js">
{
    overrideConsole: false,
    startInNewWindow: true,
    startOpened: true,
    enableTrace: true
}
</script>

这种技术叫什么名字,它是如何工作的?


这与JSONP类似吗?http://en.m.wikipedia.org/wiki/JSONP - mason
2个回答

4

这不是一种自动变量传递技术,正如你可能想的那样。

他们所有的代码都只是循环遍历所有的 script 标签,直到找到加载他们的代码的标签(通过将 src 属性与正则表达式比较(/(firebug-lite(?:-\w+)?(?:\.js|\.jgz))(?:#(.+))?$/;))。

如果找到了该标签,它只需获取 script 标签的 .innerHTML 并对其进行评估。

我猜这种(未命名的)技术在现实世界中并不相关,因为我们没有一种保证找到引用我们库的 script 标签的方法(特别是在生产服务器上常见的所有脚本都被合并成一个脚本文件的情况下)。

此外,我对这个技术在跨浏览器方面的怀疑;因为它肯定不按照 spec 的规定进行操作:

说了这个(并考虑了它):spec指出浏览器不应该解释两者。然而,这种技术与此无关。浏览器不必解释两者,因为脚本的内容通过 innerHTML 读取(即使它确实读取了内容,也不会有任何损害)。只要浏览器符合规范,并加载URI(所有浏览器都是这样做的),就没有问题!(除了不知道/保证你的库属于哪个 script 标签之外)。

脚本可以在SCRIPT元素的内容中定义,也可以在外部文件中定义。如果未设置src属性,则用户代理必须将元素的内容解释为脚本。如果src具有URI值,则用户代理必须忽略元素的内容并通过URI检索脚本。

(即不要解释两者)。

1
打开 https://getfirebug.com/firebug-lite.js 文件;并搜索 'var getScriptURL' 和 'var options=fileOptions.split(",");'。 - Theofanis Pantelides
@Theo:fileOptions是用于“脚本URL选项”(http://getfirebug.com/firebuglite#ScriptURLOptions)的。你想让我查看`getScriptUrl`是为了什么? - Matt
@Matt 我不是指你,我只是在补充你的回答。我指的是 'var url=getScriptURL(script);',这就是你所解释的发生的地方。 - Theofanis Pantelides
@Theo:啊啊啊啊啊啊啊啊 : )。我不再那么困惑了! - Matt
@Matt:干得好,先生。我一直在想这个问题,但当我看到它似乎与规范相反时,就被吓住了。所以你的意思是说,脚本标签的内容是否为JavaScript并不重要;它可以是XML、HTML或任意文本,只要我们的代码能够解释它,是吗? - Matthew Nichols
1
@Matthew:我没有考虑到将HTML/XML放在那里,但是我猜你可以这样做。我已经在最新版本的IE、Firefox和Chrome中尝试过了,如果设置了src(即使src指向无效的URI),它们都不会评估脚本内容。我仍然有点担心在其中放置非有效JS。不仅感觉不对,而且如果浏览器决定评估它,你会得到一个JS解析错误(考虑用引号/JS注释/* */将HTML/XML包装起来,使其成为有效的JS(除了转义引号等)。 - Matt

2
进一步参考@Matt的回答,并澄清我的评论:
var doc = Firebug.browser.document;
var script = doc.getElementsByTagName("script")[index];
var url = getScriptURL(script);
var isExternal = url && url != doc.location.href;

try
{
  if(isExternal)
  {
    Ajax.request({url:url, onSuccess:renderProcess, onFailure:onFailure})
  }
  else
  {
    var src = script.innerHTML;
    renderProcess(src)
  }
}
catch(e)
{
  onFailure()
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接