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) 的相关文章

  • 从函数返回函数的目的是什么?

    阅读一些遗留代码 发现 A prototype setSize function var v1 new Vector2 return function size var halfSize v1 copy size multiplyScala
  • Vue 3 Composition API 提供/注入在单文件组件中不起作用

    我正在使用 Composition API 在 VueJS 3 中创建一个库 我实现了提供 注入 如中所述docs https v3 vuejs org guide composition api provide inject html i
  • 位置特征检测:固定

    我正在尝试找到一个脚本来检测设备是否放置position fixed元素相对于视口而不是整个文档 目前 标准桌面浏览器和 Mobile Safari 适用于 iOS 5 都是这样做的 而 Android 设备则相对于整个文档放置固定元素 我
  • Angular.js:如何从无序列表中获取 orderBy 或过滤器来工作?

    尝试根据价格和评级 在返回的对象中 进行排序 我宁愿用 ng click 和 li 来代替使用选择菜单 有没有办法做到这一点 我环顾四周 这是我能想到的最接近的 ul class restaurant filter li i class i
  • 想要动态处理与分页相关的页码显示:ReactJS

    我有一些分页逻辑工作得很好 唯一的问题是我只能让它显示并固定数量的页面可供选择 现在我已经把它放到了 5 页 但我希望它能够根据总记录动态更改 假设我有 100 条记录 每页限制为 10 条 将有 10 页 现在我只能让它以这种方式显示 第
  • ReactTransitionGroup 不适用于 React-redux 连接组件

    我正在开发一个更大的项目 但我创建了这个简短的示例来说明问题 如果我使用Box组件 它的工作原理 它在控制台中输出componentWillEnter and componentWillLeave当我们点击按钮时 如果我使用BoxConta
  • javascript 选择自定义光标 (svg)

    我正在动态地将光标更改为悬停时的本地 svg element on mouseover function this css cursor url svgs pointer svg 9 30 auto 工作正常 但我想选择该 svg 来操纵其
  • React autoFocus 将光标设置为输入值的开头

    我有一个受控输入 最初显示一个值 我已将该输入设置为自动聚焦 但当我希望它出现在末尾时 光标出现在输入的开头 我知道这可能是因为自动对焦是在值之前添加的 但我不能 100 确定 在输入字段末尾完成光标初始化的最佳方法是什么 var Test
  • 如何通过单击链接来更改 div 的内容?

    这是我的网页的 修改后的 jsfiddle 它还有很多 而且定位是正确的 与此相反 http jsfiddle net ry0tec3p 1 http jsfiddle net ry0tec3p 1 a href class btn1 st
  • 如何计算特定字符在字符串中出现的次数

    我正在尝试创建一个函数来查看数组中的任何字符是否在字符串中 如果是 有多少个 我尝试计算每一种模式 但是太多了 我尝试使用 Python 中的 in 运算符的替代方案 但效果不佳 function calc fit element var
  • 改变 JavaScript 中的顶部填充

    以下是我在 css 中设置顶部填充的方法 body font size font size px margin 0 padding 100px 0 20px 0 width 100 important 如何使用最简单的 javascript
  • JavaScript eval("{}") 返回行为?

    根据ECMA 262 规范 http www ecma international org publications files ECMA ST Ecma 262 pdf 以下语句返回1 eval 1 eval 1 eval 1 var a
  • 表单发布请求并存储收到的数据

    我有一个非常简单的表单 在提交时发出发布请求
  • 用于选择特定 div 中具有特定类的锚元素的 jQuery 选择器是什么

    我有一些这样的代码 我想选择每个 a 带有类的标签status在 div 中foo div a class status a div 你可以这样做 foo find status a
  • 如何从浏览器向服务器发送“页面将关闭”消息?

    我想向每个 html 文档添加一个脚本 JavaScript 该脚本向服务器发送两条消息 页面确实打开了 页面将关闭 此消息包含页面打开的时间 打开消息应在文档加载时 或加载完成时 发送 这是简单的部分 The close message
  • 使用 Enzyme 测试 `React.createRef` api

    我想测试下面的类 它使用React createRef api 不过 快速搜索并没有发现任何这样做的例子 有人成功过吗 我该如何嘲笑裁判 理想情况下我想使用shallow class Main extends React Component
  • 滚动顶部不符合预期

    Note 由于上次忘记奖励而重新开放赏金 A Woff 大师已经给出答案 我想在用户展开某一行时到达该行 这样当最后一个可见行展开时 用户不必向下滚动即可查看内容 I used example tbody on click td green
  • Flot 库将 y 轴设置为最小值 0 和最大值 24

    如何将 y 轴设置在 0 到 24 的范围内 这是我的代码 j plot j placeholder d1 xaxis mode time min new Date 2010 11 01 getTime max new Date 2011
  • 如何通过索引访问 JSON 对象中的字段

    我知道这不是最好的方法 但我别无选择 我必须通过索引访问 JSONObject 中的项目 访问对象的标准方法是只写this objectName or this objectName 我还找到了一种获取 json 对象内所有字段的方法 fo
  • 测量窗口偏移

    有没有一种方法可以测量 jQuery 中窗口的偏移量 以便我可以比较 固定 元素和相对定位元素的位置 我需要能够知道窗口滚动了多远 以便我可以使用该图来计算固定元素的高度 相对于视口顶部 和相对对象的高度 相对于顶部 之间的差异文件的内容

随机推荐