beego on range loop re-entry: {{range}} branches end in different contexts:


在html模板js中 ``字符串模板中渲染出现的这个错误

template Execute err: html/template:xxxx/xxxx.html:34:36: on range loop re-entry: {{range}} branches end in different contexts: {stateJSRegexp delimNone urlPartNone jsCtxRegexp attrNone elementScript <nil>}, {stateJS delimNone urlPartNone jsCtxRegexp attrNone elementScript <nil>}

最后改成这样写 就没问题了

QQ图片20200912145604.png


centos7安装redis 和配置远程登录


安装redis

yum install redis

修改配置文件

cd /etc
vi redis.conf
注释掉(允许远程连接)
bind 127.0.0.1

protected-mode yes `改成` protected-mode no

# requirepass foobared `改成` requirepass `连接密码`

重启redis

systemctl restart redis

连接不上?

尝试关闭防火墙或者放行端口


golang 怎么获取url中的host | 怎么判断是否是http



package main

import (
    "fmt"
    "net/url"
    "strings"

    "github.com/asaskevich/govalidator"
)

func main() {
    rawUrl := "https://www.52bd.net/?data=111"
    changeHost := "192.168.1.1"

    if strings.Index(rawUrl, "http://") != -1 || strings.Index(rawUrl, "https://") != -1 {
        fmt.Println("是http协议")
    } else {
        fmt.Println("不是http协议")
    }

    newUrl, _ := url.Parse(rawUrl)

    // Host
    newUrlHost := newUrl.Hostname()
    // Port
    newUrlPort := newUrl.Port()
    // Path
    newUrlPath := newUrl.Path
    // URL类型转string
    stringUrl := newUrl.String()
    // 修改URl Host
    newUrl.Host = changeHost + ":900" + newUrl.Port()

    fmt.Printf("host:%s  端口:%s  path:%s  url:%s newUrl:%s  %v", newUrlHost, newUrlPort, newUrlPath, stringUrl, newUrl, govalidator.IsURL(rawUrl))
    
}


golang jwt鉴权


package model

import (
    "fmt"
    "time"

    jwt "github.com/dgrijalva/jwt-go"
)

const (
    KEY                    string = "JWT-ARY-STARK"
    DEFAULT_EXPIRE_SECONDS int    = 100000 // default 10 minutes
)

// JWT -- json web token
// HEADER PAYLOAD SIGNATURE
// This struct is the PAYLOAD
type MyCustomClaims struct {
    LpUser
    jwt.StandardClaims
}

// update expireAt and return a new token更新expireAt并返回新令牌
func RefreshToken(tokenString string) (string, error) {
    // first get previous token
    token, err := jwt.ParseWithClaims(
        tokenString,
        &MyCustomClaims{},
        func(token *jwt.Token) (interface{}, error) {
            return []byte(KEY), nil
        })
    claims, ok := token.Claims.(*MyCustomClaims)
    if !ok || !token.Valid {
        return "", err
    }
    mySigningKey := []byte(KEY)
    expireAt := time.Now().Add(time.Second * time.Duration(DEFAULT_EXPIRE_SECONDS)).Unix()
    newClaims := MyCustomClaims{
        claims.LpUser,
        jwt.StandardClaims{
            ExpiresAt: expireAt,
            Issuer:    claims.LpUser.Email,
            IssuedAt:  time.Now().Unix(),
        },
    }
    // generate new token with new claims生成带有新声明的新令牌
    newToken := jwt.NewWithClaims(jwt.SigningMethodHS256, newClaims)
    tokenStr, err := newToken.SignedString(mySigningKey)
    if err != nil {
        fmt.Println("generate new fresh json web token failed !! error :", err)
        return "", err
    }
    return tokenStr, err
}

//验证令牌
func ValidateToken(tokenString string) error {
    token, err := jwt.ParseWithClaims(
        tokenString,
        &MyCustomClaims{},
        func(token *jwt.Token) (interface{}, error) {
            return []byte(KEY), nil
        })
    if claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid {
        fmt.Printf("%v %v", claims.LpUser, claims.StandardClaims.ExpiresAt)
        fmt.Println("token will be expired at ", time.Unix(claims.StandardClaims.ExpiresAt, 0))
    } else {
        fmt.Println("validate tokenString failed !!!", err)
        return err
    }
    return nil
}

//生成令牌
func GenerateToken(user LpUser, expiredSeconds int) (tokenString string) {
    if expiredSeconds == 0 {
        expiredSeconds = DEFAULT_EXPIRE_SECONDS
    }
    // Create the Claims
    mySigningKey := []byte(KEY)
    expireAt := time.Now().Add(time.Second * time.Duration(expiredSeconds)).Unix()
    fmt.Println("token will be expired at ", time.Unix(expireAt, 0))
    // pass parameter to this func or not
    claims := MyCustomClaims{
        user,
        jwt.StandardClaims{
            ExpiresAt: expireAt,
            Issuer:    user.Name,
            IssuedAt:  time.Now().Unix(),
        },
    }
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    tokenStr, err := token.SignedString(mySigningKey)
    if err != nil {
        fmt.Println("generate json web token failed !! error :", err)
    }
    return tokenStr

}

//解析token
func ParsingToken(tokenString string) (*MyCustomClaims, error) {
    token, err := jwt.ParseWithClaims(
        tokenString,
        &MyCustomClaims{},
        func(token *jwt.Token) (interface{}, error) {
            return []byte(KEY), nil
        })
    if claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid {
        fmt.Printf("%v %v", claims.LpUser, claims.StandardClaims.ExpiresAt)
        fmt.Println("token will be expired at ", time.Unix(claims.StandardClaims.ExpiresAt, 0))
        return claims, nil
    } else {
        fmt.Println("validate tokenString failed !!!", err)
        return nil, err
    }
}


bootstrap4 表单验证以ajax的方式提交 非submit表单提交


<div className="row ">
        <div className="col-sm">
          你好:)
        </div>
        <div className="col-sm">
          <div className="shadow p-3 mb-5 bg-white rounded">
          <form id="register_form" method="post" action="/api/register" >
            <div className="form-group">
              <label>Name</label>
              <input type="text" name="name" className="form-control" id="name" required onChange={(event) => SetInputRequestObj(event)}/>
            </div>
            <div className="form-group">
              <label>Email address</label>
              <input type="email" name="email" className="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="name@example.com" required onChange={(event) => SetInputRequestObj(event)}/>
              <small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
            </div>
            <div className="form-group">
              <label>Password</label>
              <input type="password" name="passwd" className="form-control" id="exampleInputPassword1" required onChange={(event) => SetInputRequestObj(event)}/>
            </div>
           
            <button type="submit" className="btn btn-primary" onClick={(event) => {subForm() }}>Submit</button>
          </form>
          </div>
        </div>
        
      </div>
function subForm(){
    //阻止默认提交事件
    $("#register_form").submit(function(e){
      e.preventDefault();
    })  

    let valiRes = false; 
    //$('#register_form')是要验证的目标表单
    Array.prototype.filter.call($('#register_form'), function (target) {
      valiRes = target.checkValidity();
    }); 

    //valiRes就是表单验证的结果,返回一个bool值
    if(!valiRes)
      return;//表单验证未通过
    
    // 提交数据
    $.ajax({
      type: "post",
      url: "/api/register",
      data: JSON.stringify(RequestObj),
      contentType: "application/json;charset=utf-8",
      dataType: "json",
      success: function(data){
        
      }
    });
  }

beego validation无效、失效 golang tag标签的一个坑


来看看结构体

这样 自己用table键吧tag标签搞得整整齐齐的

type People struct {
    Key     string `json:"key"         form:"key"         valid:"Required"`         //id值
    Name    string `json:"name"     form:"name"     valid:"Required"`         //名字
    Idcard  string `json:"idcard"     form:"idcard"     valid:"Length(18)"`   //身份证
    Iccard  string `json:"iccard"     form:"iccard"`                       //IC卡号
    Sex     int    `json:"sex"         form:"sex"         valid:"Required;Numeric"` //1男 2女
    Picture string `json:"picture"     form:"picture"     valid:"Base64"`     //照片 base64
}

然后我们反射一下看看结果

package main

import (
    "fmt"
    "reflect"
)

type People struct {
    Key     string `json:"key"         form:"key"         valid:"Required"`         //id值
    Name    string `json:"name"     form:"name"     valid:"Required"`         //名字
    Idcard  string `json:"idcard"     form:"idcard"     valid:"Length(18)"`   //身份证
    Iccard  string `json:"iccard"     form:"iccard"`                       //IC卡号
    Sex     int    `json:"sex"         form:"sex"         valid:"Required;Numeric"` //1男 2女
    Picture string `json:"picture"     form:"picture"     valid:"Base64"`     //照片 base64
}

func main() {

    people := People{
        Key: "ccc",
    }

    t := reflect.TypeOf(people)

    for i := 0; i < t.NumField(); i++ {
        key := t.Field(i)
        valid := key.Tag.Get("valid")
        fmt.Println(valid)
    }

}

果然输出结果是空的

2020-07-23T00:50:54.png

然后我们把结构体中的tag标签用空格分开

2020-07-23T00:52:37.png

再执行 反射成功!

2020-07-23T00:53:09.png


结论:

结构体tag标签中不能使用table键(可以用多个空格键,或者不用空格)

centos安装brook教程


1.安装Nami
curl https://raw.githubusercontent.com/txthinking/nami/master/install.sh | bash && sleep 6 && exec -l $SHELL
2.通过Nami安装brook
nami install github.com/txthinking/brook

2020-07-19T02:42:53.png

3.后台运行ws模式的brook
nohup brook wsserver -l 0.0.0.0:端口 -p 密码 &

如果连接不上 需要关闭防火墙或者端口放行