【问题标题】:Displaying line breaks produced by html/template in Go on GAE在 GAE 上显示由 html/template 生成的换行符
【发布时间】:2016-07-06 23:29:52
【问题描述】:

我的应用程序是用 Go 编写的。应用程序的页面从 HTML 文本区域接收用户数据,这些数据作为字符串数据保存到 Google App Engine 数据存储区。然后,在应用程序的另一个页面上,它需要以用户在 HTML 文本区域中键入的格式显示数据,或者至少在用户在 HTML 文本字段中键入数据时按 Enter 键时保留换行符。

我尝试使用<pre> 标签来显示用户在文本字段中输入的保留换行符,效果很好。但是,我发现有一个双标签

\t\t

在使用 <pre> 标签时插入字符串的开头,我可以使用 Javascript 删除双标签。

我的想法是保留用户在文本字段中键入的换行符是使用 javascript 替换功能将所有 \r\n\n\r 替换为 <br>,但是,它没有成功.似乎 Go 没有将换行符输出到 html 源代码中。出于安全原因,我使用“html/template”,但我没想到它会从其输出中完全删除\r\n 字符。对于字符串开头的奇怪双标签\t\t有什么建议吗?

【问题讨论】:

  • 我也替换了\n,我也没有解决。我正在使用 Linux。

标签: javascript html string google-app-engine go


【解决方案1】:

不要在javascript中将换行符更改为<br>,而是在Go中进行:http://play.golang.org/p/jJXMZxtYcv

package main

import (
    "html/template"
    "log"
    "os"
    "strings"
)

func main() {
    const tpl = `
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{{.Title}}</title>
    </head>
    <body>
        <div>{{nl2br .Text}}</div>
    </body>
</html>`

    check := func(err error) {
        if err != nil {
            log.Fatal(err)
        }
    }

    funcs := template.FuncMap{
        "nl2br": func(text string) template.HTML {
            return template.HTML(strings.Replace(template.HTMLEscapeString(text), "\n", "<br>", -1))
        },
    }

    t, err := template.New("webpage").Funcs(funcs).Parse(tpl)
    check(err)

    data := struct {
        Title string
        Text  string
    }{
        Title: "My page",
        Text:  "\t\tLine 1\r\nLine2\r\n",
    }

    err = t.Execute(os.Stdout, data)
    check(err)
}

【讨论】:

  • 你试过template.New(name).Funcs(funcs).ParseFiles(name)吗?
  • 是的,这正是我所做的。它编译但在请求时显示错误。 http: panic serving 127.0.0.1:36496: runtime error: invalid memory address or nil pointer dereference 在调用templates.Execute 之后。当我在调用templates.Execute 之前使用template.Must(template.ParseFiles("page.html") 时,它起作用了。我处理了错误,但错误不是从我的处理程序中抛出的,而是由 Go 的恐慌函数抛出的。
  • 这很奇怪,它在操场上是这样工作的:play.golang.org/p/WKDhEm3qJj
  • 解决了!我只需要将New(name) 中的模板名称命名为ParseFiles(name) 函数中的名称。感谢 user1431317!
  • 哦,是的,很抱歉,如果我的评论中不明显的话。
【解决方案2】:

您可以简单地解决 CSS 格式问题,即 white-space 属性:

white-space 属性指定如何处理元素内的空白。

CSS 语法:

white-space: normal|nowrap|pre|pre-line|pre-wrap|initial|inherit;

pre 值的作用就像将其包装在 HTML &lt;pre&gt; 标记中,该标记也将呈现双标签。

使用pre-line 值对您有用:

pre-line 空白序列将折叠成一个空白。文本将在必要时换行,并在换行符处

所以行被保留,但多个空格被折叠成一个。优点是您不需要转换原始文本,浏览器将应用正确的格式。代码仍然可以安全地抵御 HTML 注入攻击。

完整示例:

func main() {
    t := template.Must(template.New("").Parse(src))
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        t.Execute(w, text)
    })
    panic(http.ListenAndServe("localhost:8080", nil))
}

const src = `<html><body>Entered text:
<div style="white-space:pre-line">{{.}}</div>
</body></html>`

const text = "\t\t1st line\n2nd line\r\n3rdline"

你最初的双标签\t\t

请注意,您的初始双标签 \t\t 不是由浏览器或表单提交(如果您将其存储在数据存储中)生成的,但很可能是您使用缩进 2 个标签的模板的结果。模板的缩进也会写入输出,因此您应该正确关闭您的&lt;textarea&gt;,模板中没有换行符。由于您没有发布您的模板和代码,我无法提供更多帮助来找出您为什么有初始双标签,但您应该找到根本原因而不是治疗症状。

【讨论】:

  • 谢谢你,icza。你是围棋英雄!
  • 非常有用的答案!
猜你喜欢
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-09
  • 2010-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-19
相关资源
最近更新 更多