Разбор HTML-кода на странице, отображаемой в виде простого текста, с шаблоном go - PullRequest
0 голосов
/ 18 мая 2018

Я начал использовать язык Go и сейчас пытаюсь создать HTML-страницу.Я совершенно новичок в программировании на Go и HTML.

В программе Go я пытаюсь разобрать HTML-страницу (div) в главную HTML-страницу (index.html), которую пытаюсь добавитьэтот div для главной html-страницы с использованием шаблона в Go.

html-страница, на которой я пытаюсь проанализировать данные, выглядит следующим образом:

<html>
<head>
    <meta charset="utf-8">
    <title>SmartHomePi Status</title>
    <link rel="stylesheet" href="../static/css/style.css">
</head>
<body>
    <h1>HomeControl Connection Status</h1>
    <div id="wrapper" width="100%">
        {{.SonoffBasic}}
    </div>
</body>

{{.SonoffBasic}} - это часть, где я пытаюсь добавить свой div.Элемент div, который я пытаюсь добавить, выглядит следующим образом:

<div id="sonoffbasicdevice">
    <span class="%connectiondotclass%"></span>
    <p id="title">%title%</p>
    <p id="tempandhum">%humstatus%</p>
    <p id="ipaddress">%ipaddress%</p>
    <p id="portnumber">%portnumber%</p>
</div>

Все значения с% xxx% анализируются, чтобы содержать полезную информацию, и все идет правильно.

Но теперь яя пытаюсь проанализировать эти 2 вместе с помощью шаблона в Go, и здесь, кажется, что-то идет не так.

Я делаю это с помощью следующей функции в Go:

func renderHomeKitTemplate(w http.ResponseWriter, tmpl string, items *WebPageHTMLItems) {
    err := templates.ExecuteTemplate(w, "index.html", items)
} 

Гдепеременные items - это структура, которая выглядит следующим образом:

type WebPageHTMLItems struct{
    SonoffBasic  string
}

где строка theSonoffBasic содержит div со всей заполненной информацией.

Веб-страницу можно просматривать, когда я запускаю программу, но когдавеб-страница показывается, вместо того, чтобы анализировать div, она отображается в виде простого текста, что я делаю здесь неправильно?HTML code shown as text

Это даже правильный способ для разбора данных в файл HTML.Причина, по которой я использую этот способ добавления полного div, заключается в том, что я могу иметь несколько элементов «sonoffbasicdevice» и должен добавить несколько из них.

1 Ответ

0 голосов
/ 18 мая 2018

Использование template.HTML

html/template обеспечивает автоматическое контекстно-зависимое экранирование, защищенное от внедрения кода:

Шаблоны HTML обрабатывают значения данных как простыетекст, который должен быть закодирован, чтобы его можно было безопасно встроить в документ HTML.Экранирование является контекстным, поэтому действия могут появляться в контекстах JavaScript, CSS и URI.

В пакете html/template есть специальный тип: template.HTML.Значения этого типа в шаблоне не экранируются при визуализации шаблона.

Поэтому измените тип WebPageHTMLItems.SonoffBasic на template.HTML, и он будет отображаться как есть:

type WebPageHTMLItems struct{
    SonoffBasic template.HTML
}

template.HTML имеет string в качестве базового типа, поэтому для установки этого поля из значения string используйте простое преобразование типов:

params := &WebPageHTMLItems{
    SonoffBasic: template.HTML("<div>...</div>"),
}

Слово предупреждения: это не защитит отвнедрение кода!Например, когда вы подставляете %title% и он содержит код JavaScript, он будет пропущен к выводу и, наконец, выполнен в клиентских браузерах.

Использование действия {{template}}

Также обратите внимание, что вы можете определить <div> как отдельный именованный шаблон и просто использовать действие {{template}}, чтобы включить его на свою страницу, что-то вроде этого:

{{define "sonoffbasicdevice"}}
    <div id="sonoffbasicdevice">
        <span class="%connectiondotclass%"></span>
        <p id="title">%title%</p>
        <p id="tempandhum">%humstatus%</p>
        <p id="ipaddress">%ipaddress%</p>
        <p id="portnumber">%portnumber%</p>
    </div>
{{end}}

И в шаблоне вашей страницы:

<div id="wrapper" width="100%">
    {{template "sonoffbasicdevice"}}
</div>

Также обратите внимание, что для полной безопасности вы можете также создавать и передавать параметры в шаблон sonoffbasicdevice, как и в любой другой, и позволить пакету html/template позаботиться обезопасное, контекстно-зависимое замещение:

{{define "sonoffbasicdevice"}}
    <div id="sonoffbasicdevice">
        <span class="{{.Connectiondotclass}}"></span>
        <p id="title">{{.Title}}</p>
        <p id="tempandhum">{{.Humstatus}}</p>
        <p id="ipaddress">{{.Ipaddress}}</p>
        <p id="portnumber">{{.Portnumber}}</p>
    </div>
{{end}}

Затем вы должны включить его следующим образом (для передачи предназначенных для него параметров):

<div id="wrapper" width="100%">
    {{template "sonoffbasicdevice" .SonoffBasic}}
</div>

Выполнение этого «мульти-шаблона» можетвыглядеть так:

type SonoffBasic struct {
    Connectiondotclass string
    Title              string
    Humstatus          string
    Ipaddress          string
    Portnumber         string
}

type WebPageHTMLItems struct{
    SonoffBasic *SonoffBasic
}

params := &WebPageHTMLItems{
    SonoffBasic: &SonoffBasic{
        Connectiondotclass: "someclass",
        Title:              "sometitle",
        Humstatus:          "somestatus",
        Ipaddress:          "someip",
        Portnumber:         "someport",
    },
}

err := templates.ExecuteTemplate(w, "index.html", params)
...