You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法通过模板操作DOM增删属性,如何用Go服务端控制输入框禁用状态?

解决方案

通过Go html/template 内置的自定义函数能力,在服务端渲染阶段直接完成权限判断和属性输出,完全不需要前端JS介入,避免前端篡改权限的安全风险,同时减少冗余代码。

1. 调整Go后端代码

新增模板自定义权限判断函数,把权限校验逻辑放到服务端处理:

package main

import (
    "context"
    "html/template"
    "net/http"
    "strings"
    "time"
)

type User struct {
    Flags string
    Title string
}

type UsersPageData struct {
    PageTitle string
    Users     []User
}

func requestTime(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ctx := r.Context()
        ctx = context.WithValue(ctx, "requestTime", time.Now().Format(time.RFC3339))
        r = r.WithContext(ctx)
        next.ServeHTTP(w, r)
    })
}

// 权限判断函数:检查用户的flags里是否包含允许的权限项
func hasPermission(userFlags string, allowedPerms []string) bool {
    userPerms := strings.Fields(userFlags)
    permMap := make(map[string]bool)
    for _, p := range userPerms {
        permMap[p] = true
    }
    for _, allowed := range allowedPerms {
        if permMap[allowed] {
            return true
        }
    }
    return false
}

func helloHandler(name string) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        var title string
        if requestTime := r.Context().Value("requestTime"); requestTime != nil {
            if str, ok := requestTime.(string); ok {
                title = "\ngenerated at: " + str
            }
        }

        master := strings.Join([]string{"admin", "user", "superuser", "read"}, " ")
        admin := strings.Join([]string{"admin"}, " ")
        user := strings.Join([]string{"user"}, " ")

        // 当前用户允许的权限列表,和你之前JS里的flags对应
        allowedPerms := []string{"admin", "superuser"}

        // 注册自定义模板函数
        funcMap := template.FuncMap{
            "hasPermission": func(userFlags string) bool {
                return hasPermission(userFlags, allowedPerms)
            },
        }

        // 注意顺序:先绑定FuncMap再解析模板文件
        tmpl := template.Must(template.New("index.html").Funcs(funcMap).ParseFiles("index.html"))
        data := UsersPageData{
            PageTitle: "Users list: " + title,
            Users: []User{
                {Flags: master, Title: "Everything"},
                {Flags: admin, Title: "Administrator"},
                {Flags: user, Title: "Normal user"},
            },
        }
        tmpl.Execute(w, data)
    })
}

func main() {
    http.Handle("/john", requestTime(helloHandler("John")))
    http.ListenAndServe(":8080", nil)
}

2. 修改HTML模板

删除所有权限判断的JS代码,直接在模板中做条件渲染:

<style>
.admin {
    color: green;
}

.user {
    color: red;
    --btn-disable: 0;
}


[data-authorized="no"] {
        cursor: not-allowed;
        pointer-events: none;
        color: #c0c0c0;
        background-color: rgb(229, 229, 229) !important;
}

</style>
<h1>{{.PageTitle}}</h1>
<ul>
    {{range .Users}}
            <li><input type="text" {{if not (hasPermission .Flags)}}data-authorized="no"{{end}}> {{.Title}}</li>
    {{end}}
</ul>

优化建议

你可以直接使用HTML原生的disabled属性代替自定义data-authorized属性,语义更标准,也不需要额外的自定义属性选择器:
把模板里的input标签改为:

<input type="text" {{if not (hasPermission .Flags)}}disabled{{end}}>

CSS直接适配input:disabled选择器即可。


内容的提问来源于stack exchange,提问作者Hasan A Yousef

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 10:06:03