我在Google Apps脚本中创建了函数,当我在Google Apps脚本中运行该函数时效果很好。输出数据返回到Google表格。
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”。 当我单击按钮时,它会返回
{
"message": "An error has occurred."
}
看起来像来自API服务器的响应。
我唯一的假设是Google工作表的按钮添加了一些标头,User-Agent或content-type来请求,这是API服务器中不允许的。经过一些搜索,我想我无法在请求中重新分配User-Agent。那是对的还是我做错了?
编辑1:
每种情况console.log(UrlFetchApp.getRequest(url, params))
的标题:
在电子表格中单击按钮时:
{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不允许更改此值。
将尝试在邮递员中使用不同的标题,并可能确认此标题是导致错误的原因。谢谢@TheMaster
编辑2:
我通过邮递员尝试了不同的标题。因此,结果是当我将具有任何值的标头添加到标头X-Forwarded-For
时,它返回"message": "An error has occurred."
当我不添加此键时,它会很好地工作。
因此,问题是通过Google Apps脚本禁用添加此标头的任何方法。好像没有。
答案 0 :(得分:1)
UrlFetchApp.fetch()
时,X-Forwarded-For
会自动添加到标题中。X-Forwarded-For
添加到标题中,会发生An error has occurred.
的错误。X-Forwarded-For
,不会发生错误。如果我的理解是正确的,该解决方法如何?我认为可能有几种解决方法。因此,请仅考虑其中之一。在这种解决方法中,Web Apps用作包装器功能。
首先,请复制并粘贴以下脚本。并将testFunction11()
设置为按钮。运行testFunction11()
时,testFunction11()
向Web Apps(doGet()
)请求,而Web Apps向https://api.apiservice.com/api/v1/xxx?fields=somefields
请求。这样,X-Forwarded-For
就不会用于请求的标头。然后,返回Web Apps的结果,并将值放入电子表格中。 在运行脚本之前,请先部署Web Apps。
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。
答案 1 :(得分:1)
有关此主题的以后搜索:我遇到了一个完全相同的错误消息,我使用UrlFetchApp#getRequest
作为实用程序来生成请求对象,然后使用UrlFetchApp#fetchAll
发送它。 / p>
解决方案是避免使用getRequest
,而是由我自己建立请求,而不使用任何X-Forwarded-For
标头,这样可以使请求成功完成。
我找不到任何文档来支持此操作,但是我推测发生了以下问题:当Google在发出请求之前注入X-Forwarded-For
标头时,其注入的IP取决于脚本获取的上下文我认为Google会验证,如果该标头是手动设置的,则IP地址需要匹配其GAS代理的IP或用户的浏览器IP;哪个脚本似乎会根据脚本执行的上下文而改变。