以前寫了一篇爲:golang web實戰之一(beego,mvc postgresql)css
據說iris更好:html
1. iris hello world前端
package main import "github.com/kataras/iris" func main() { app := iris.New() app.Get("/", func(ctx iris.Context) { //ctx.HTML(`<p>hello world!</p>`) //ctx.Writef("\n\n host: %s \n\n path: %s \n\n request:%s ", ctx.Host(), ctx.Path(), ctx.Request()) //ctx.JSON(iris.Map{"message": "ping", "reply": "pong"}) ctx.Text("hello world!") }) app.Run(iris.Addr(":8080")) }
2.路由git
2.1用正則檢查url路徑是否符合要求github
package main import ( "github.com/kataras/iris" ) func main() { app := iris.New() //regexp來驗證路徑參數。分別匹配大寫、小寫字母。若包含數字等,則不會匹配 //eg. http://localhost:8080/ANYUPPERCASE/anylowercase app.Get("/{first:string regexp(^[A-Z]+)}/{second:string regexp(^[a-z]+)}", func(ctx iris.Context) { ctx.Writef("first should be only UPPERCASE:%s,second should be only lowercase:%s, otherwise this handler will never executed!", ctx.Params().Get("first"), ctx.Params().Get("second")) }) app.Run(iris.Addr(":8080")) }
2.2 url路徑包含整數golang
package main import ( "github.com/kataras/iris" ) func main() { app := iris.New() //eg. http://localhost:8080/123 app.Get("/{page:int}", func(ctx iris.Context) { p, _ := ctx.Params().GetInt("page") ctx.Writef("page:%d", p) }) app.Run(iris.Addr(":8080")) }
3. 靜態文件服務器web
3.1.經過輸入url訪問靜態目錄下的靜態文件sql
package main import ( "github.com/kataras/iris" ) func main() { app := iris.New() app.StaticWeb("/static", "./assets") // eg: http://localhost:8080/static/css/main.css app.Run(iris.Addr(":8080")) //路由不容許.StaticWeb("/","./ assets") }
3.2文件下載json
package main import ( "github.com/kataras/iris" ) func main() { app := iris.New() app.Get("/", func(ctx iris.Context) { file := "./main.go" ctx.SendFile(file, "main.go") }) app.Run(iris.Addr(":8080")) }
4.模板輸出(模板hello.html存放於view/main/下面)segmentfault
package main import ( "github.com/kataras/iris" ) func main() { /* //views/main/hello.html的內容 <html> <head> <title>{{ .Page.Title }}</title> </head> <body> <h1> Hello {{.Page.Name}}from index.html </h1> <script src="/app.js"> </script> </body> </html> */ type page struct { Title, Name string } app := iris.New() app.RegisterView(iris.HTML("./views", ".html")) // 方法: GET // 資源: http://localhost:8080 app.Get("/", func(ctx iris.Context) { //綁定數據 ctx.ViewData("Page", page{Title: "Hi Page", Name: "iris"}) // 渲染視圖文件: ./views/hello.html ctx.View("main/hello.html") }) app.Run(iris.Addr(":8080")) }
5.上傳文件
package main import ( "io" "os" "github.com/kataras/iris" ) const maxSize = 5 << 20 // 5MB var tpl = ` <html> <head> <title>Upload file</title> </head> <body> <form enctype="multipart/form-data" action="http://127.0.0.1:8080/upload" method="POST"> <input type="file" name="uploadfile" /> <input type="hidden" name="token" value="{{.}}" /> <input type="submit" value="upload" /> </form> </body> </html> ` func main() { app := iris.New() app.Get("/upload", func(ctx iris.Context) { ctx.HTML(tpl) }) //處理來自upload_form.html的請求數據處理 //用iris.LimitRequestBodySize的好處是:在上傳過程當中,若檢測到文件大小超過限制,就會當即切斷與客戶端的鏈接。 app.Post("/upload", iris.LimitRequestBodySize(maxSize+1<<20), func(ctx iris.Context) { // Get the file from the request. file, info, err := ctx.FormFile("uploadfile") if err != nil { ctx.StatusCode(iris.StatusInternalServerError) ctx.HTML("Error while uploading: <b>" + err.Error() + "</b>") return } defer file.Close() fname := info.Filename //建立一個具備相同名稱的文件 //假設你有一個名爲'uploads'的文件夾 out, err := os.OpenFile("./uploads/"+fname, os.O_WRONLY|os.O_CREATE, 0666) if err != nil { ctx.StatusCode(iris.StatusInternalServerError) ctx.HTML("Error while uploading: <b>" + err.Error() + "</b>") return } defer out.Close() io.Copy(out, file) }) //在http//localhost:8080啓動服務器,上傳限制爲5MB。 app.Run(iris.Addr(":8080") /* 0.*/, iris.WithPostMaxMemory(maxSize)) }
6.cookies
package main import "github.com/kataras/iris" func newApp() *iris.Application { app := iris.New() app.Get("/cookies/{name}/{value}", func(ctx iris.Context) { name := ctx.Params().Get("name") value := ctx.Params().Get("value") ctx.SetCookieKV(name, value) // 另外也能夠用: ctx.SetCookie(&http.Cookie{...}) ctx.Request().Cookie(name) //若是您但願僅對當前請求路徑可見: //(請注意,若是服務器發送空cookie的路徑,全部瀏覽器都兼容,將會使用客戶端自定義路徑) // ctx.SetCookieKV(name, value, iris.CookieCleanPath /* or iris.CookiePath("") */) // 學習更多: // iris.CookieExpires(time.Duration) // iris.CookieHTTPOnly(false) ctx.Writef("cookie added: %s = %s", name, value) }) app.Get("/cookies/{name}", func(ctx iris.Context) { name := ctx.Params().Get("name") value := ctx.GetCookie(name) // <-- 檢索,獲取Cookie //判斷命名cookie不存在,再獲取值 // cookie, err := ctx.Request().Cookie(name) // if err != nil { // handle error. // } ctx.WriteString(value) }) app.Get("/cookiesd/{name}", func(ctx iris.Context) { name := ctx.Params().Get("name") ctx.RemoveCookie(name) // <-- 刪除Cookie //若是要設置自定義路徑: // ctx.SetCookieKV(name, value, iris.CookiePath("/custom/path/cookie/will/be/stored")) ctx.Writef("cookie %s removed", name) }) return app } func main() { app := newApp() // GET: http://localhost:8080/cookies/my_name/my_value // GET: http://localhost:8080/cookies/my_name // DELETE: http://localhost:8080/cookiesd/my_name app.Run(iris.Addr(":8080")) }
7.jwt
package main import ( "fmt" "time" "github.com/dgrijalva/jwt-go" ) var ( SIGN_NAME_SCERET = "aweQurt178BNI" ) func main() { fmt.Println("Hello World!") tokenString, err := createJwt() if err != nil { fmt.Println(err.Error()) return } fmt.Println(tokenString) claims := parseJwt(tokenString) fmt.Println(claims) } //驗證 //在調用Parse時,會進行加密驗證,同時若是提供了exp,會進行過時驗證; //若是提供了iat,會進行發行時間驗證;若是提供了nbf,會進行發行時間驗證. //建立 tokenString func createJwt() (string, error) { // token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ // "foo": "bar", // "nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(), // }) token := jwt.New(jwt.SigningMethodHS256) claims := make(jwt.MapClaims) claims["foo"] = "bar" claims["exp"] = time.Now().Add(time.Hour * time.Duration(1)).Unix() claims["iat"] = time.Now().Unix() token.Claims = claims // Sign and get the complete encoded token as a string using the secret tokenString, err := token.SignedString([]byte(SIGN_NAME_SCERET)) return tokenString, err } //解析tokenString func parseJwt(tokenString string) jwt.MapClaims { token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { // Don't forget to validate the alg is what you expect: if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) } // hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key") return []byte(SIGN_NAME_SCERET), nil }) var claims jwt.MapClaims var ok bool if claims, ok = token.Claims.(jwt.MapClaims); ok && token.Valid { fmt.Println(claims["foo"], claims["nbf"]) } else { fmt.Println(err) } return claims }
關於JWT 這篇 https://blog.csdn.net/idwtwt/article/details/80865209 詳解的較清楚
很安全的方式就是把 XSRF Token 加入到 JWT ( JSON Web Token)中,而且把 JWT 存放在設置 httpOnly 的 cookie 中,而後單獨把 XSRF Token 設置在 httpOnly=false 的 cookie 中,前端請求時,須要獲取 XSRF Token 並放入請求頭(RequestHeader)。服務器端能夠直接驗證JWT中XSRF的值和XSRF的值便可。由於用了哈希密鑰簽名的技術,這樣就能夠防止篡改內容。
這樣的安全防禦就能抵禦全部的 XSRF 攻擊了。
另外, 儘可能不用GET而用POST ,可過濾用戶輸入,填寫驗證碼等.....
個人理解是,jwt和session區別只是一個放在用戶client端、一個放在服務器server端。能夠相互代替()。
8.iris自定義結構體映射獲取Form表單請求數據
// package main包含一個關於如何使用ReadForm的示例,但使用相同的方法能夠執行ReadJSON和ReadJSON /* //templates/form.html <!DOCTYPE html> <head> <meta charset="utf-8"> </head> <body> <form action="/form_action" method="post"> Username: <input type="text" name="Username" /> <br /> Mail: <input type="text" name="Mail" /> <br /> Select one or more: <br/> <select multiple="multiple" name="mydata"> <option value='one'>第一</option> <option value='two'>第二</option> <option value='three'>第三</option> <option value='four'>第四</option> </select> <hr /> <input type="submit" value="Send data"/> </form> </body> </html> */ package main import ( "github.com/kataras/iris" ) type Visitor struct { Username string Mail string Data []string `form:"mydata"` } func main() { app := iris.New() //設置視圖html模板引擎 app.RegisterView(iris.HTML("./views", ".html").Reload(true)) app.Get("/", func(ctx iris.Context) { if err := ctx.View("form.html"); err != nil { ctx.StatusCode(iris.StatusInternalServerError) ctx.WriteString(err.Error()) } }) app.Post("/form_action", func(ctx iris.Context) { visitor := Visitor{} err := ctx.ReadForm(&visitor) if err != nil { ctx.StatusCode(iris.StatusInternalServerError) ctx.WriteString(err.Error()) } //%#v 相應值的 Go 語法表示; %+v 會添加字段名 ; %% 字面上的百分號,並不是值的佔位符 ctx.Writef("Visitor: %#v", visitor) }) app.Post("/post_value", func(ctx iris.Context) { username := ctx.PostValueDefault("Username", "iris") ctx.Writef("Username: %s", username) }) app.Run(iris.Addr(":8080")) }
9.讀取配置文件
/* //config.json { "appname": "IrisDemo", "port": 8000 } */ package main import ( "encoding/json" "fmt" "os" "github.com/kataras/iris" ) type Coniguration struct { Appname string `json:appname` Port int64 `json:port` } func main() { app := iris.New() app.Get("/", func(ctx iris.Context) { file, _ := os.Open("config.json") defer file.Close() decoder := json.NewDecoder(file) conf := Coniguration{} err := decoder.Decode(&conf) if err != nil { fmt.Println("Error:", err) } fmt.Println(conf.Port) ctx.WriteString(conf.Appname) }) app.Run(iris.Addr(":8080")) }
10. golang iris web項目熱重啓
在開發web的時候,若是項目不支持熱重啓,每添加或修改個接口都須要重啓項目才能測試,會很麻煩。都知道beego有bee工具,bee run
啓動項目便可,而在iris項目中熱重啓方法以下
# 安裝rizla包 $ go get -u github.com/kataras/rizla # 熱重啓方式啓動iris項目 $ rizla main.go
http://www.javashuo.com/article/p-bmnvapps-ke.html
http://www.javashuo.com/article/p-xkmqxnbx-y.html
https://blog.csdn.net/tianwenxue/article/details/84998517
https://blog.csdn.net/idwtwt/article/details/80865209
https://www.jianshu.com/p/af8360b83a9f
http://www.javashuo.com/article/p-wnmnixmk-hz.html
http://www.javashuo.com/article/p-fohdfxmp-gz.html
http://www.javashuo.com/article/p-auklggsg-bm.html
https://blog.csdn.net/weixin_43420337/article/details/86151619
http://www.javashuo.com/article/p-cnftdfvx-nc.html
http://www.javashuo.com/article/p-epbwyhrn-kz.html
https://studygolang.com/articles/1741
github