Google Apps 脚本:模板化 HTML scriptlet 中的换行符

Google Apps Script: Line breaks in templated HTML scriptlets

如果我有一个 HTML 文件 test.html:

<p><?= str ?></p>

还有一个脚本函数:

var t = HtmlService.createTemplateFromFile("test.html");
t.str = "test\nstring";
var content = t.evaluate().setSandboxMode(...).getContent();
Logger.log(content);

有什么方法可以安全地用 HTML 换行符替换换行符?我可以使用 String.prototype.replace() 将 \n 替换为 <br/>,但是我必须使用 <?!= 来禁用 HTML 模板引擎的上下文转义。我正在处理不受信任的输入,因此我需要对换行符进行转义和智能处理。在上下文中使用它会很好。就目前情况而言,我编写了自己的转义器,但它只适用于一种情况。

我看到了两种适合您的情况的选择,最简单的一种是完全忘记替换并使用

 标记,这将呈现您的换行符(和其他格式字符)

<pre> <?= str ?> </pre>

第二个是执行替换并使用自定义函数清理您的输入,以便您可以安全地使用强制打印脚本。

在你的html中:

<?!= sanitize(str); ?>

并在您的 .gs 中:

function sanitize(val){ var vals = val.split('\n'); //split string into an array on newlines for(var i in vals){ vals[i] = Encoder.htmlEncode(vals[i]); //sanitize each element in the array } return vals.join('<br />'); //join the elements as a string, with <br /> as glue. }

请注意,在我的示例中,我使用位于此处的库来清理字符串:http://www.strictly-software.com/scripts/downloads/encoder.js

如果有人好奇,这是我最后用来清理不受信任的输入以供显示的代码。在标签内部、脚本部分等中使用它是不安全的。这就是为什么 Google 的上下文感知清理非常方便。

function dumbEscapeAndBreak(str) {
  return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br/>');
}

function _testEscape() {
  GSUnit.assertEquals('my&lt;test&lt;string&gt;is&gt;not&amp;good&amp;okay<br/>fine<br/>okay', dumbEscapeAndBreak("my<test<string>is>not&good&okay\nfine\nokay"));
}

或者您可以这样做:

在您的 .gs 脚本函数中:

var t = HtmlService.createTemplateFromFile("test.html");
var paragraphs = "test\nstring";
t.str = paragraphs.split("\n");

在你的test.html中:

<?
for (i = 0; i < str.length; i++) {
?>
   <span><?= str[i]?></span><br />
   <!-- <p><?= str[i]?></p> -->
<?
}
?>

您可以使用 <span><p> 标签,这取决于您。您还可以编写一些简单的逻辑来决定何时放置 <br />,例如<span> 之前 i > 0。那将完全满足你的"test\nstring".