将 URL 参数传递到 Web 应用脚本中

Pass URL parameter into Web App script

本文关键字:应用 脚本 Web URL 参数传递      更新时间:2023-09-26

这个问题让我想拔掉头发。 我正在尝试将URL参数传递给Google Apps Script,其中包含我要呈现的数据的行ID(来自电子表格)。 我的参数是story。 但是,无论我尝试什么,我都会遇到各种错误。 最新的是:

类型错误: 无法从未定义读取属性"参数"。(第 2 行,文件"代码",项目"单故事")

以下是我的 Code.gs 和索引.html文件(该项目尚未完成。 这就是我目前所处的位置。

Code.gs

function doGet(e) {
    var i = e.parameter.story;
    return HtmlService
      .createTemplateFromFile('Index')
      .evaluate()
      .setSandboxMode(HtmlService.SandboxMode.IFRAME);
 function getData() {
 return SpreadsheetApp
      .openById("1Z582cnr03fkLC7xCca4pcj7QwDtSCS4KGneyFKMgdyo")
      .getSheetByName("StoryTopics")
      .getDataRange()
      .getValues();
 }
}

索引.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
  <? var data = doGet(); ?>
<div id="container">
<div id="header">
<div id="topicname">
    <?= data[i][0] ?>
</div>
<div id="todaysdate">
<p>As of: <?= new Date() ?></p>
</div>
<div id="topictype">
<?= data[i][1] ?>
</div>
<div id="locale">
<?= data[i][2] ?>
</div>
</div>
<div id="contact_container">
<div id="subheader">
</div>
<div id="contact_name">
<?= data[i][3] ?>
</div>
<div id="contact_title">
<?= data[i][4] ?>, <?= data[i][5] ?>
</div>
<div id="contact_email">
<?= data[i][6] ?>
</div>
<div id="contact_phone">
<?= data[i][7] ?>
</div>
</div>
<div id="action_container">
<div id="subheader">
</div>
<table id="action_table">
<tr>
<td>
Date:
</td>
<td>
Type:
</td>
<td>
Description:
</td>
</tr>
</table>
</div>
<div id="story_container">
<div id="story_title">
</div>
<div id="story_content">
</div>
</div>
</div>
</body>
</html>

我用来测试的 URL + 参数是:

https://script.google.com/a/macros/--DOMAIN--/s/--SCRIPTID--/exec?story=3

谁能给我一些关于为什么它不起作用的想法?

类型错误: 无法从未定义读取属性"参数"。(第 2 行,文件"代码",项目"单故事")

这告诉您希望包含命名属性"参数"的对象是未定义的。

查看您的代码(e.parameter.story),这是指事件参数 e 。对于那些不熟悉此内容的人,在已部署的 Web 应用中调用它时,特别命名的 doGet() 函数会收到一个事件参数,在本示例中名为 e

为什么这里没有定义e

你可能会看到这种情况的一个原因是,如果你从调试器运行函数,而不是将其作为 Web 应用进行测试。凯文,这不是您的情况,因为您正在浏览器中输入 URL 以尝试启动 Web 应用程序。

问题出在模板化的 HTML 中。HTML 中的第一个语句是:

<? var data = doGet(); ?>

一旦我们尝试.evaluate()模板,这就会造成麻烦,因为它会重新调用 doGet() 函数,这次没有任何事件对象。正是那个时候吐出了错误消息。

您可能打算这样做,而是从电子表格中获取数据:

<? var data = getData(); ?>

完成该更改后,您现在会收到事件参数e(您一直这样做...),并且代码继续。直到下一个错误:

引用错误:"i"未定义。(第 3 行,文件"代码")

现在事情变得棘手了,因为错误是在 Code.gs 中针对此语句报告的:

return HtmlService
    .createTemplateFromFile('Index')
    .evaluate()
    .setSandboxMode(HtmlService.SandboxMode.IFRAME);

但是等等!i不是在第 2 行中定义的吗?是的,是...但是,此错误是关于evaluate()尝试填写模板,并且您的代码尚未为此设置i。您需要分解此语句以首先获取模板,然后为其设置参数,最后对其进行评估。喜欢这个:

function doGet(e) {
  var i = e.parameter.story;
  // First, get the template
  var template = HtmlService.createTemplateFromFile('Index');
  // Second, set template parameters
  template.i = i;
  // Finally, evaluate() the template
  return template.evaluate()
                 .setSandboxMode(HtmlService.SandboxMode.IFRAME);
}  // <-- You had this on the other side of 'getData()'

这应该会让你滚滚而来。您还有其他错误:

  • 阻止您的函数是错误的,您希望在全局范围内getData(),而不是在doGet()范围内。
  • 可能需要调试模板
  • ,请按照调试模板中的指导进行操作。
  • 模板化代码被括在<? thusly ?>,而不是<?= like this ?>