"在全局范围内调用方法UrlFetchApp.fetch." Google Apps脚本Ediotor执行提示

Hua*_*uan 9 google-sheets google-apps-script

我正在谷歌应用脚​​本编辑器中开发一个谷歌电子表格插件.

正如https://developers.google.com/apps-script/add-ons/lifecycle所说,有时脚本以限制授权模式运行,因此我们不会在全局范围内编写任何需要高权限的代码(如UrlFetch).

警告:运行onOpen(e)函数时,将加载整个脚本并执行任何全局语句.这些语句在与onOpen(e)相同的授权模式下执行,如果模式禁止它们将失败.这可以防止onOpen(e)运行.如果您发布的加载项无法添加其菜单项,请在浏览器的JavaScript控制台中查看是否抛出错误,然后检查脚本以查看onOpen(e)函数或全局变量是否调用不允许的服务在AuthMode.NONE中.

但我发现了一个"在全球范围内调用"的非常奇怪的行为.我将所有代码放在闭包中,并调用它们,但仍然警告说我在全局范围内运行UrlFetchApp.

最后,我发现"在全球范围内运行"与"非全局"之间的区别,是因为第一个是var g = function () { /* UrlFetchApp here */ },第二个是function ng() { /* UrlFetchApp here */ ].

以下代码可以在Google Script Editor中运行.如果使用Tg()运行testGlobalScope(),将收到警告.不管怎样,只运行T.ng(),没关系.

var T = (function() {
  var g = function () {
    // Method UrlFetchApp.fetch invoked in the global scope.
    try { UrlFetchApp.fetch('http://google.com') } catch (e) {}
  }

  function ng() {
    try { UrlFetchApp.fetch('http://google.com') } catch (e) {}
  }

  return {
    g: g
    , ng: ng
  }

}())

function testGlobalScope() {
  T.g() // T.g() will cause Script Editor show "Execution Hints" with red light: Method UrlFetchApp.fetch invoked in the global scope.
//  T.ng() // This will not show any warning.
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 为什么他们有这种差异?
  2. 如果我仍然想使用像var T =(function(){}())这样的模块模式,我怎么能摆脱"在全局范围内运行"的问题呢?

a-c*_*nge 2

这个问题相当老了,但会尽力回答。

0)虽然警告确实显示在脚本编辑器中,但onOpen即使没有向脚本授予权限,它似乎也不会阻止函数运行。因此,显示警告可能没有实际原因。

0.1) 尽管如此,它还是会显示,并且您声明的精确程度并不重要T:无论是function T()var T = function T() { ... }还是var T = (function() { ... }()),都会显示警告。

1)不太清楚,只能根据以上和以下进行假设(也许Execution hints会认为任何匿名函数都属于全局作用域?)。

2)但看起来有一种方法可以消除警告,同时仍然将函数声明为表达式,尽管g需要是命名函数:

var T = (function() {
  var g = function g() {
    // No "Method UrlFetchApp.fetch invoked in the global scope." warning
    try { UrlFetchApp.fetch('http://google.com') } catch (e) {}
  }

  function ng() {
    try { UrlFetchApp.fetch('http://google.com') } catch (e) {}
  }

  return {
    g: g
    , ng: ng
  }

})()
Run Code Online (Sandbox Code Playgroud)