Go實戰--也許最快的Go語言Web框架kataras/iris初識四(i18n、filelogger、recaptcha)
生命不止,繼續 go go go !!!
繼續分享關於kataras/iris框架
i18n
i18n(其來源是英文單詞 internationalization的首末字元i和n,18為中間的字元數)是“國際化”的簡稱。在資訊領域,國際化(i18n)指讓產品(出版物,軟體,硬體等)無需做大的改變就能夠適應不同的語言和地區的需要。對程式來說,在不修改內部程式碼的情況下,能根據不同語言及地區顯示相應的介面。 在全球化的時代,國際化尤為重要,因為產品的潛在使用者可能來自世界的各個角落。通常與i18n相關的還有L10n(“本地化”的簡稱)。
新建資料夾locales,新建三個檔案配置檔案,分別對應中文、英文、希臘文:
locale_zh-CN.ini
hi = 您好,%s
locale_en-US.ini
hi = hello, %s
locale_el-GR.ini
hi = γεια, %s
main.go程式碼:
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/middleware/i18n"
)
func newApp() *iris.Application {
app := iris.New()
app.Use(i18n.New(i18n.Config{
Default: "en-US" ,
URLParameter: "lang",
Languages: map[string]string{
"en-US": "./locales/locale_en-US.ini",
"el-GR": "./locales/locale_el-GR.ini",
"zh-CN": "./locales/locale_zh-CN.ini"}}))
app.Get("/", func(ctx context.Context) {
hi := i18n.Translate(ctx, "hi" , "iris")
language := ctx.Values().GetString(ctx.Application().ConfigurationReadOnly().GetTranslateLanguageContextKey())
ctx.Writef("From the language %s translated output: %s", language, hi)
})
return app
}
func main() {
app := newApp()
// go to http://localhost:8080/?lang=el-GR
// or http://localhost:8080
// or http://localhost:8080/?lang=zh-CN
app.Run(iris.Addr(":8080"))
}
瀏覽器輸入:localhost:8080
由於我的PC是中文,所以顯示:
From the language zh-CN translated output: 您好,iris
通過curl訪問:
curl localhost:8080
結果:From the language en-US translated output: hello, iris
filelogger
主要是用於http log to file.
(不推薦使用)
main,.go
package main
import (
"os"
"time"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
)
// get a filename based on the date, file logs works that way the most times
// but these are just a sugar.
func todayFilename() string {
today := time.Now().Format("2006-01-02")
return today + ".txt"
}
func newLogFile() *os.File {
filename := todayFilename()
// open an output file, this will append to the today's file if server restarted.
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
return f
}
func main() {
f := newLogFile()
defer f.Close()
app := iris.New()
// attach the file as logger, remember, iris' app logger is just an io.Writer.
app.Logger().SetOutput(newLogFile())
app.Get("/", func(ctx context.Context) {
// for the sake of simplicity, in order see the logs at the ./_today_.txt
ctx.Application().Logger().Info("Request path: " + ctx.Path() + "\n")
ctx.Writef("hello")
})
if err := app.Run(iris.Addr(":8080"), iris.WithoutBanner); err != nil {
if err != iris.ErrServerClosed {
app.Logger().Warn("Shutdown with error: " + err.Error())
}
}
}
recaptcha
CMU 設計了一個名叫 reCAPTCHA 的強大系統,讓他們的電腦去向人類求助。具體做法是:將 OCR 軟體無法識別的文字掃描圖傳給世界各大網站,用以替換原來的驗證碼圖片,這些網站的使用者在正確識別出這些文字之後,其答案便會被傳回CMU。所以 reCAPTCHA 本質上是一個披著驗證碼皮的分散式文字識別系統(OCR)。
reCAPTCHA 是利用 CAPTCHA(全自動區分計算機和人類的圖靈測試) 的原理藉助於人類大腦對難以識別的字元的辨別能力,進行對古舊書籍中難以被 OCR 識別的字元進行辨別的技術。也就是說,reCAPTCHA 不僅可以反 spam(垃圾內容),而且同時還可以幫助進行古籍的數字化工作(可以稱為人工OCR)。只能說這個創意簡直是絕了!所以即便由於 reCAPTCHA 是 Google 的產品在國內無法正常使用,但還是會應用到我們的這個 Blog 專案中,再通過應用反向代理的方式使之成為可行。
使用
在註冊一個 Google 使用者名稱後,進入到 reCAPTCHA 官網 並輸入你的 blog 名(隨意填寫)和域名(只支援域名和子域名,現在我們暫時使用 localhost,等部署到線上之後也需要將新的域名填入),就會得到一個 Public Key,就可以把它用在你的 reCAPTCHA 外掛上了,同時 reCAPTCHA 也支援多個站點。
main.go
package main
import (
"fmt"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/middleware/recaptcha"
)
// publicDataSiteKey and secretKey and should be obtained by https://www.google.com/recaptcha.
const (
publicDataSiteKey = "6LfiVjcUAAAAAJyjCEGVyTpmFqlpOMGVIZpZPy6p"
secretKey = "6LfiVjcUAAAAAJ7wALWYNew2yx0qbT0WxRR-kYu9"
)
func main() {
app := iris.New()
r := recaptcha.New(secretKey)
app.Get("/comment", showRecaptchaForm)
// pass the middleware before the main handler or use the `recaptcha.SiteVerify`.
app.Post("/comment", r, postComment)
app.Run(iris.Addr(":8080"))
}
var htmlForm = `<form action="/comment" method="POST">
<script src="https://www.google.com/recaptcha/api.js"></script>
<div class="g-recaptcha" data-sitekey="%s"></div>
<input type="submit" name="button" value="Verify">
</form>`
func showRecaptchaForm(ctx context.Context) {
contents := fmt.Sprintf(htmlForm, publicDataSiteKey)
ctx.HTML(contents)
}
func postComment(ctx context.Context) {
// [...]
ctx.JSON(context.Map{"success": true})
}
// 20171106141744
// http://localhost:8080/comment
{
"success": true
}