如何为按钮分配基本授权的UrlFetchApp?

时间:2019-02-10 11:06:31

标签: google-apps-script get basic-authentication urlfetch

我在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脚本禁用添加此标头的任何方法。好像没有。

2 个答案:

答案 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应用程序:

在运行此脚本之前,请部署Web Apps。

  • 在脚本编辑器上
  • 发布->部署为Web App
    1. 创建新的项目版本
    2. 在“执行应用”上,选择“我”
    3. 在“谁有权访问该应用”中,
      • 如果该功能仅由您使用,请选择“仅我自己”。
      • 如果该功能已被多个用户使用,请选择“任何人”。
    4. 点击“部署”
    5. 复制“当前的Web应用程序URL”
    6. 点击“确定”

注意:

  • 修改脚本后,请重新部署Web Apps作为新版本。这样,最新的脚本就会反映到Web Apps。这很重要。
  • 这是一个简单的示例脚本。因此,请根据您的情况进行修改。

参考文献:

答案 1 :(得分:1)

有关此主题的以后搜索:我遇到了一个完全相同的错误消息,我使用UrlFetchApp#getRequest作为实用程序来生成请求对象,然后使用UrlFetchApp#fetchAll发送它。 / p>

解决方案是避免使用getRequest,而是由我自己建立请求,而不使用任何X-Forwarded-For标头,这样可以使请求成功完成。

我找不到任何文档来支持此操作,但是我推测发生了以下问题:当Google在发出请求之前注入X-Forwarded-For标头时,其注入的IP取决于脚本获取的上下文我认为Google会验证,如果该标头是手动设置的,则IP地址需要匹配其GAS代理的IP或用户的浏览器IP;哪个脚本似乎会根据脚本执行的上下文而改变。