如何将具有基本权限的 UrlFetchApp 分配给按钮?
How to assign UrlFetchApp with basic authorization to button?
我在 Google Apps 脚本中创建了函数,当我在 Google Apps 脚本中 运行 它时效果很好。输出数据 returns 到 Google Sheets.
function testFunction11() {
var rng = SpreadsheetApp.getActiveRange();
var encodedAuthInformation = Utilities.base64Encode("username:key");
var headers = {"Authorization" : "Basic " + encodedAuthInformation};
var params = {
'method': 'GET',
'muteHttpExceptions': true,
'headers': headers
};
var res = UrlFetchApp.fetch("https://api.apiservice.com/api/v1/xxx?fields=somefields", params);
Logger.log(res.getContentText());
rng.setValue(res);
}
单元格中的输出:
[
{
"id": xxx,
"createdDate": "2019-02-01T04:54:00Z",
"reference": "XXX"
},
etc
然后我将脚本分配给按钮,'testFunction11'。
当我点击按钮时,它 returns
{
"message": "An error has occurred."
}
看起来像是来自 API 服务器的响应。
我唯一的假设是 google sheet 的按钮添加了一些 header , User-Agent 或 content-type 来请求,这是不允许的API 服务器。经过一番搜索,我想我无法在请求中重新分配 User-Agent 。这是对的还是我做错了?
编辑 1:
Headers 每个案例 console.log(UrlFetchApp.getRequest(url, params))
:
当点击 spreadsheet 中的按钮时:
{headers={Authorization=Basic XXXXXXXXQVU6MWVhODlmZmFkN2U3NGNjOGJkOTc1YTE1ZjVhNTE3MzE=, X-Forwarded-For=178.xx.my.ip}, method=get, payload=, followRedirects=true, validateHttpsCertificates=true, useIntranet=false, contentType=null, url=https://api.apisite.com/api/v1/SalesOrders?fields=Id,Createddate,Reference&where=Createddate%3E2019-02-01T00:00:00Z}
对于脚本:
{headers={Authorization=Basic XXXXXXXXQVU6MWVhODlmZmFkN2U3NGNjOGJkOTc1YTE1ZjVhNTE3MzE=}, method=get, payload=, followRedirects=true, validateHttpsCertificates=true, useIntranet=false, contentType=null, url=https://api.apisite.com/api/v1/SalesOrders?fields=Id,Createddate,Reference&where=Createddate%3E2019-02-01T00:00:00Z}
所以按钮只添加了X-Forwarded-For
.
当我尝试手动添加时 X-Forwarded-For: 'unknown'
出现这样的错误
There are attribute with impossible value: Header:X-Forwarded-For
俄语错误文本,很抱歉翻译可能不准确。这很有趣,因为当我以同样的方式添加 Test: unknown
时,没有错误,但显然不起作用。看起来 google 不允许更改此值。
将在 postman 中尝试不同的 headers 并可能确认此 header 是错误的原因。谢谢@TheMaster
编辑 2:
我通过 Postman 尝试了不同的 headers。所以,结果是当我用任何值添加到 headers X-Forwarded-For
键时,它 return "message": "An error has occurred."
当我不添加此密钥时,它运行良好。
因此,问题是通过 Google Apps 脚本禁用添加此 header 的任何方式。好像不是。
- 在您的情况下,当
UrlFetchApp.fetch()
是来自电子表格上的按钮的 运行 时,X-Forwarded-For
会自动添加到 header。
- 将
X-Forwarded-For
添加到header,出现An error has occurred.
的错误。
- 另一方面,
X-Forwarded-For
没有在 header 中使用,不会发生错误。
如果我的理解是正确的,这个解决方法怎么样?我认为可能有几种解决方法。所以请把这当作其中之一。在此解决方法中,Web 应用程序用作包装函数。
示例脚本:
首先,请复制并粘贴以下脚本。请将 testFunction11()
设置为按钮。当 testFunction11()
为 运行 时,testFunction11()
请求网络应用程序 (doGet()
),网络应用程序请求 https://api.apiservice.com/api/v1/xxx?fields=somefields
。至此,X-Forwarded-For
不用于请求的 header。然后,返回 Web Apps 的结果并将值放入电子表格。 请在 运行 脚本之前部署 Web 应用程序。
function testFunction11() {
var rng = SpreadsheetApp.getActiveRange();
var url = ScriptApp.getService().getUrl();
var params = {method: "get", headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}};
var res = UrlFetchApp.fetch(url, params);
Logger.log(res.getContentText());
rng.setValue(res);
}
function doGet() {
var url = "https://api.apiservice.com/api/v1/xxx?fields=somefields";
var encodedAuthInformation = Utilities.base64Encode("username:key");
var headers = {"Authorization" : "Basic " + encodedAuthInformation};
var params = {
'method': 'GET',
'muteHttpExceptions': true,
'headers': headers
};
var res = UrlFetchApp.fetch(url, params);
return ContentService.createTextOutput(res.getContentText());
}
部署网络应用程序:
在你运行这个脚本之前,请先部署Web Apps。
- 在脚本编辑器上
- 发布 -> 部署为 Web 应用程序
- 创建新的项目版本
- 在 "Execute the app a" 秒,select "Me"
- 在 "Who has access to the app",
- 如果该功能只有你一个人使用,select "Only myself".
- 如果该功能被多个用户使用,select "Anyone"。
- 点击"Deploy"
- 复制"Current web app URL"
- 点击"OK"
注:
- 修改脚本后,请重新部署 Web Apps 为新版本。这样,最新的脚本就会反映到 Web Apps。 这是一个重点。
- 这是一个简单的示例脚本。所以请根据你的情况修改。
参考文献:
对于此主题的未来搜索:我遇到了完全相同的错误消息问题,我使用 UrlFetchApp#getRequest
作为生成请求 object 的实用程序,然后使用 UrlFetchApp#fetchAll
.
解决方案是避免使用 getRequest
而是自己构建请求 而不使用任何 X-Forwarded-For
header,这允许请求成功完成。
我找不到任何文档来支持这一点,但我推测发生了以下问题:当 Google 在发出请求之前注入 X-Forwarded-For
header 时,它注入的 IP 取决于脚本执行的上下文。我认为 Google 验证如果 header 是手动设置的,那么 IP 地址需要匹配他们的 GAS 代理的 IP 或用户的浏览器 IP ;使用哪个似乎取决于脚本执行的上下文。
我在 Google Apps 脚本中创建了函数,当我在 Google Apps 脚本中 运行 它时效果很好。输出数据 returns 到 Google Sheets.
function testFunction11() {
var rng = SpreadsheetApp.getActiveRange();
var encodedAuthInformation = Utilities.base64Encode("username:key");
var headers = {"Authorization" : "Basic " + encodedAuthInformation};
var params = {
'method': 'GET',
'muteHttpExceptions': true,
'headers': headers
};
var res = UrlFetchApp.fetch("https://api.apiservice.com/api/v1/xxx?fields=somefields", params);
Logger.log(res.getContentText());
rng.setValue(res);
}
单元格中的输出:
[
{
"id": xxx,
"createdDate": "2019-02-01T04:54:00Z",
"reference": "XXX"
},
etc
然后我将脚本分配给按钮,'testFunction11'。 当我点击按钮时,它 returns
{
"message": "An error has occurred."
}
看起来像是来自 API 服务器的响应。
我唯一的假设是 google sheet 的按钮添加了一些 header , User-Agent 或 content-type 来请求,这是不允许的API 服务器。经过一番搜索,我想我无法在请求中重新分配 User-Agent 。这是对的还是我做错了?
编辑 1:
Headers 每个案例 console.log(UrlFetchApp.getRequest(url, params))
:
当点击 spreadsheet 中的按钮时:
{headers={Authorization=Basic XXXXXXXXQVU6MWVhODlmZmFkN2U3NGNjOGJkOTc1YTE1ZjVhNTE3MzE=, X-Forwarded-For=178.xx.my.ip}, method=get, payload=, followRedirects=true, validateHttpsCertificates=true, useIntranet=false, contentType=null, url=https://api.apisite.com/api/v1/SalesOrders?fields=Id,Createddate,Reference&where=Createddate%3E2019-02-01T00:00:00Z}
对于脚本:
{headers={Authorization=Basic XXXXXXXXQVU6MWVhODlmZmFkN2U3NGNjOGJkOTc1YTE1ZjVhNTE3MzE=}, method=get, payload=, followRedirects=true, validateHttpsCertificates=true, useIntranet=false, contentType=null, url=https://api.apisite.com/api/v1/SalesOrders?fields=Id,Createddate,Reference&where=Createddate%3E2019-02-01T00:00:00Z}
所以按钮只添加了X-Forwarded-For
.
当我尝试手动添加时 X-Forwarded-For: 'unknown'
出现这样的错误
There are attribute with impossible value: Header:X-Forwarded-For
俄语错误文本,很抱歉翻译可能不准确。这很有趣,因为当我以同样的方式添加 Test: unknown
时,没有错误,但显然不起作用。看起来 google 不允许更改此值。
将在 postman 中尝试不同的 headers 并可能确认此 header 是错误的原因。谢谢@TheMaster
编辑 2:
我通过 Postman 尝试了不同的 headers。所以,结果是当我用任何值添加到 headers X-Forwarded-For
键时,它 return "message": "An error has occurred."
当我不添加此密钥时,它运行良好。
因此,问题是通过 Google Apps 脚本禁用添加此 header 的任何方式。好像不是。
- 在您的情况下,当
UrlFetchApp.fetch()
是来自电子表格上的按钮的 运行 时,X-Forwarded-For
会自动添加到 header。 - 将
X-Forwarded-For
添加到header,出现An error has occurred.
的错误。 - 另一方面,
X-Forwarded-For
没有在 header 中使用,不会发生错误。
如果我的理解是正确的,这个解决方法怎么样?我认为可能有几种解决方法。所以请把这当作其中之一。在此解决方法中,Web 应用程序用作包装函数。
示例脚本:
首先,请复制并粘贴以下脚本。请将 testFunction11()
设置为按钮。当 testFunction11()
为 运行 时,testFunction11()
请求网络应用程序 (doGet()
),网络应用程序请求 https://api.apiservice.com/api/v1/xxx?fields=somefields
。至此,X-Forwarded-For
不用于请求的 header。然后,返回 Web Apps 的结果并将值放入电子表格。 请在 运行 脚本之前部署 Web 应用程序。
function testFunction11() {
var rng = SpreadsheetApp.getActiveRange();
var url = ScriptApp.getService().getUrl();
var params = {method: "get", headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}};
var res = UrlFetchApp.fetch(url, params);
Logger.log(res.getContentText());
rng.setValue(res);
}
function doGet() {
var url = "https://api.apiservice.com/api/v1/xxx?fields=somefields";
var encodedAuthInformation = Utilities.base64Encode("username:key");
var headers = {"Authorization" : "Basic " + encodedAuthInformation};
var params = {
'method': 'GET',
'muteHttpExceptions': true,
'headers': headers
};
var res = UrlFetchApp.fetch(url, params);
return ContentService.createTextOutput(res.getContentText());
}
部署网络应用程序:
在你运行这个脚本之前,请先部署Web Apps。
- 在脚本编辑器上
- 发布 -> 部署为 Web 应用程序
- 创建新的项目版本
- 在 "Execute the app a" 秒,select "Me"
- 在 "Who has access to the app",
- 如果该功能只有你一个人使用,select "Only myself".
- 如果该功能被多个用户使用,select "Anyone"。
- 点击"Deploy"
- 复制"Current web app URL"
- 点击"OK"
注:
- 修改脚本后,请重新部署 Web Apps 为新版本。这样,最新的脚本就会反映到 Web Apps。 这是一个重点。
- 这是一个简单的示例脚本。所以请根据你的情况修改。
参考文献:
对于此主题的未来搜索:我遇到了完全相同的错误消息问题,我使用 UrlFetchApp#getRequest
作为生成请求 object 的实用程序,然后使用 UrlFetchApp#fetchAll
.
解决方案是避免使用 getRequest
而是自己构建请求 而不使用任何 X-Forwarded-For
header,这允许请求成功完成。
我找不到任何文档来支持这一点,但我推测发生了以下问题:当 Google 在发出请求之前注入 X-Forwarded-For
header 时,它注入的 IP 取决于脚本执行的上下文。我认为 Google 验证如果 header 是手动设置的,那么 IP 地址需要匹配他们的 GAS 代理的 IP 或用户的浏览器 IP ;使用哪个似乎取决于脚本执行的上下文。