UrlFetchApp 请求在菜单功能中失败,但在自定义功能中失败(连接到外部 REST API)

2023-11-29

我使用以下函数连接到外部 API (Binance),使用 Google Apps 脚本检索 JSON 数组(市场价格)。这个简单的查询 URL 在浏览器中运行良好(不需要 API 密钥):

function getMyArray() {
  var url ="https://api.binance.com/api/v3/ticker/price"; // works perfectly in browser
  var params =  {"method"  : "get",  "muteHttpExceptions":true };  
  var response = UrlFetchApp.fetch(url, params);
  var array = JSON.parse(response.getContentText());
  
  return array;
}

然而,当我尝试在 Google Apps 脚本中运行该函数时,情况就不同了:

  1. 脚本编辑器:在脚本编辑器中运行简单实用,但我得到了403 error“请求被阻止”
  2. 菜单功能:从添加到电子表格 UI 的菜单项调用该函数 => 相同403 error
  3. 自定义功能:编辑任意单元格并输入=getMyArray()=> 请求有效,我可以使用 Logger 跟踪数组

为什么我的简单请求在从菜单或脚本编辑器调用时被阻止,是否可以更改?谢谢


When UrlFetchApp由自定义函数和脚本编辑器使用,我认为区别在于是否使用IPv6,而IPv4的地址每次运行都会改变。在这种情况下,脚本编辑器和自定义菜单的结果是相同的。我认为这可能是您问题的原因。但我不确定我的猜测是否正确。因此,在这个答案中,我想提出以下解决方法。

  1. Put the formula =getMyArray() to a cell using the script.
    • 这样,值就被检索到单元格中。
  2. 使用脚本从单元格中检索值。
  3. 清除看跌期权公式。

通过这个流程,我认为你的目标可以实现。

示例脚本如下。

示例脚本:

在此脚本中,作为测试,=getMyArray()被放入活动工作表上的单元格“A1”,并从该单元格中检索该值。使用此功能时,请运行该功能main()在脚本编辑器和自定义菜单中。这样,就可以将值检索到array.

function getMyArray() {
  var url = "https://api.binance.com/api/v3/ticker/price";
  var params =  {"method": "get", "muteHttpExceptions": true};
  var response = UrlFetchApp.fetch(url, params);
  return response.getContentText();
}

// Please run this function by the script editor and the custom menu.
function main() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var range = sheet.getRange("A1");
  range.setFormula("=getMyArray()");
  SpreadsheetApp.flush();
  var value = range.getValue();
  range.clearContent();
  var array = JSON.parse(value);
  console.log(array)
}

参考:

  • Google 表格中的自定义函数
  • 设置公式()
  • flush()

Added:

响应值来自https://httpbin.org/get如下。

用于测试此功能的示例脚本:

function sample() {
  var url = "https://httpbin.org/get";
  var res = UrlFetchApp.fetch(url);
  console.log(res.getContentText())
  return res.getContentText();
}

Result:

Pattern 1. Script is run with the script editor.
{
  "args": {}, 
  "headers": {
    "Accept-Encoding": "gzip,deflate,br", 
    "Host": "httpbin.org", 
    "User-Agent": "Mozilla/5.0 (compatible; Google-Apps-Script; beanserver; +https://script.google.com; id: ###)", 
    "X-Amzn-Trace-Id": "Root=###"
  }, 
  "origin": "### IPV6 ###, ### IPV4 ###", // or "### IPV4 ###, ### IPV4 ###"
  "url": "https://httpbin.org/get"
}
  • 当您使用 IPV6 时,origin is "### IPV6 ###, ### IPV4 ###"。但是当你使用IPV4时,origin is "### IPV4 ###, ### IPV4 ###".
  • 在这种情况下,无法从中检索到正确的值https://api.binance.com/api/v3/ticker/price.
Pattern 2. Script is run with the custom function.

在这种情况下,=sample()被放入单元格并检索该值。

{
  "args": {}, 
  "headers": {
    "Accept-Encoding": "gzip,deflate,br", 
    "Host": "httpbin.org", 
    "User-Agent": "Mozilla/5.0 (compatible; Google-Apps-Script; beanserver; +https://script.google.com; id: ###)", 
    "X-Amzn-Trace-Id": "Root=###"
  }, 
  "origin": "### IPV4 ###", 
  "url": "https://httpbin.org/get"
}
  • 在这种情况下,可以从以下位置检索正确的值https://api.binance.com/api/v3/ticker/price.
Pattern 3. Script is run with the OnEdit event trigger.

When UrlFetchApp与自定义功能配合使用,无需授权。但当UrlFetchApp与OnEdit事件触发器一起使用,授权需要安装可安装的触发器。我以为这个授权可能会出现这个问题。所以我就这样比较了。

When UrlFetchApp与可安装的 OnEdit 事件触发器一起使用,将检索以下结果。

{
  "args": {}, 
  "headers": {
    "Accept-Encoding": "gzip,deflate,br", 
    "Host": "httpbin.org", 
    "User-Agent": "Mozilla/5.0 (compatible; Google-Apps-Script; beanserver; +https://script.google.com; id: ###)", 
    "X-Amzn-Trace-Id": "Root=###"
  }, 
  "origin": "### IPV4 ###", 
  "url": "https://httpbin.org/get"
}
  • 这个结果和上面的模式2是一样的。
  • 在这种情况下,可以从以下位置检索正确的值https://api.binance.com/api/v3/ticker/price.

Result:

  • 标头包括User-Agent所有模式都相同。
  • 从模式2和模式3来看,与Google方的授权无关。
  • When WHOIS with IPV4 is retrieved, the same result is returned.
    • When origin is "### IPV4 ###, ### IPV4 ###",第二个IPV4是Google的IP地址。

从上面的结果来看,所有模式的不同之处在于是否origin是1或2。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UrlFetchApp 请求在菜单功能中失败,但在自定义功能中失败(连接到外部 REST API) 的相关文章

  • 这段代码有什么问题。如果用户选择或不选择复选框,为什么它仍然显示 MsgBox? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 无论我是否选择复选框 它仍然会给出
  • JS 在两个或多个点之间画线

    我需要在两个标签或标签之间画一条线 Example http caitriona github io connect the dots http caitriona github io connect the dots 我需要做这样的事情
  • setTimeout 用于加载下拉列表中的项目

    我在用setTimeout克服 中提到的缓慢处理脚本警告 禁用 Internet Explorer 中的长时间运行脚本消息 https stackoverflow com questions 4460263 disabling the lo
  • 有没有办法将 Google 文档分割成多个 PDF?

    我想在 Google Scripts VBA 代码中复制我为 Word 文档编写的代码 基本上 它通过搜索我插入文档中的标签 将文档 切片 为多个 PDF 文件 目的是允许合唱团使用 forScore 管理乐谱的应用程序 在切片点插入先前注
  • Javascript - 使数组索引 toLowerCase() 不起作用

    我试图将所有数组索引设置为小写字符串 但它不起作用 我在这里查看了其他答案并尝试了他们的解决方案 例如使用toString 添加之前toLowerCase但它不起作用 这很奇怪 我创建了一个问题的jsfiddlehere https jsf
  • 我可以用一个简单的函数制作一个迭代器吗? (没有生成器或 Symbol.iterator)

    我一直在尝试使用普通函数创建一个迭代器 而不使用生成器或使用Symbol iterator用于学术目的的协议 为此 我创建了一个函数 它返回一个带有next参数 但尝试将其作为iterable的论证for of循环会产生不需要的结果 这是到
  • 光标:IE 8 和 9 中的自动行为

    我想要的是为整个正文标记指定cursor pointer 这样页面的背景是可点击的 但我也希望页面的其余部分像以前一样工作 所以我尝试为div设置cursor auto 其中包含这一页 在 FF Chrome 和 safari 中 它工作得
  • Express JS:请求的资源上不存在“Access-Control-Allow-Origin”标头

    我有一个在服务器上运行的 API 和一个连接到它以检索数据的前端客户端 我对跨域问题做了一些研究并使其发挥作用 但我不确定发生了什么变化 我现在在控制台中收到此错误 XMLHttpRequest 无法加载https api mydomain
  • TypeError:cli.init 不是 React Native 的函数

    在 MacBook Air M1 芯片中运行 npx react native init appName 时 TypeError cli init is not a function at run opt homebrew lib node
  • 在each() 和forEach() 中使用break 和 continue

    如果我们不能使用 break 和 continue 关键字 我不确定我是否理解函数式循环 映射的价值 我可以做这个 collections users models forEach function item index can t use
  • 在Javascript中将RGB数组转换为RGBA数组的快速方法

    我正在使用的模拟器在内部存储 RGB 值的一维帧缓冲区 但是 HTML5 画布在调用 putImageData 时使用 RGBA 值 为了显示帧缓冲区 我当前循环遍历 RGB 数组并以某种方式创建一个新的 RGBA 数组与此类似 https
  • Moment.js 动态更新时间(以秒为单位)

    我试图显示时钟 that 每秒更新一次 e g 2015 年 1 月 5 日 12 05 01 它似乎对我来说工作得很好 对于相同的代码 并且只有 moment min js 指向v2 11 0 看看代码 来源 MilkyWayJoe va
  • 使用淘汰赛动态显示/隐藏元素

    我有一个表 有四列 即代码 名称 数量和价格 其中 我想动态更改数量列的内容 元素 通常 它应该显示其中显示数量的元素 当用户单击元素时 我想显示该元素 以便用户可以编辑数量 我正在尝试按照 示例2 来实现淘汰赛文档链接 http knoc
  • 如何检查侧边栏视图是否已经在主干中渲染?

    通常 用户通过主页进入网站 然后我在那里渲染侧边栏视图 接下来 用户单击链接 路由器呈现另一个视图并替换原始内容视图 侧边栏视图不会重新渲染 当用户在子页面上单击刷新时 侧边栏不会呈现 如何检查视图是否存在并且已渲染 划分责任并坚持下去 不
  • UpdatePanel 启动脚本未执行

    我正在编写一个在 SharePoint 网站中使用的 ASP NET Web 部件 并尝试使用 UpdatePanel 来呈现查询结果 我想使用 JQuery 插件来修改从异步回发返回的表 但我无法让启动脚本在异步更新上执行 我发现这个帖子
  • 如何获取 Spotify API 的访问令牌?

    我已经研究 Spotify api 和示例源代码几天了 但我仍然不知道如何获取访问令牌来访问用户的播放列表数据 我已经到达了拉起登录窗口 用户登录 然后收到授权码的地步 此时 我尝试做这样的事情 window open https acco
  • 在 Windows 上静默安装 Qt55 Enterprise

    编辑 在 Qt 支持的帮助下 我已经解决了如何自动化 Qt 企业安装程序的这两个部分 下面是脚本调用 我正在尝试在 Windows 8 1 和 Windows 10 上静默安装 Qt 5 5 1 Enterprise 使用 script 开
  • Ajax 函数在重定向后不保存滚动位置

    正如标题所述 我编写了一个 ajax 函数 该函数应该滚动到用户在重定向之前所在的位置 我写了一个alert对于测试场景 它确实触发了 但滚动不断回到顶部 我在这里做错了什么 JavaScript ajax type GET url Adm
  • 如何更改数据表中标题单元格的内容?

    我正在使用数据表 http datatables net plugin 在我的可排序列上 我想用按钮替换列文本 但是这样做 oSettings aoColumns i nTh text 我可以检索相应列的文本 但是 oSettings ao
  • “memset”没有 DLL 那么如何 ctype 它

    如何使用memset在 jsc 类型中 没有对应的 DLL 我搜索 搜索了 js ctype 代码 但找不到要破解的示例 如果你只是想memset一个数组为零字节 然后我有 好消息 大家 js ctypes 会将新数组初始化为零 否则 最简

随机推荐