處理 web 程序的輸入與輸出
文章目錄
文章目錄
概述
設計一個 web 小應用,展示靜態文件服務、js 請求支持、模板輸出、表單處理、Filter 中間件設計等方面的能力。(不需要數據庫支持)
任務要求
編程 web 應用程序 cloudgo-io。 請在項目 README.MD 給出完成任務的證據!
基本要求
- 支持靜態文件服務
- 支持簡單 js 訪問
- 提交表單,並輸出一個表格
- 對
/unknown
給出開發中的提示,返回碼5xx
完成基本要求
1. 框架選擇
首先需要選擇一個golang框架來進行開發,看了許多前輩的博客都說iris好,我想既然都沒使用過那就隨便選一個吧·~·
目前網上關於iris的教程比較少,主要參考前輩博客和官方文檔。
官方網站給出的安裝指令:
go get -u github.com/kataras/iris
但是因爲部分依賴包被牆了,是無法安裝成功的,下面給出翻牆之外的方法。
先找到安裝不成功的包,通過在get命令中使用-v參數看到安裝的詳細過程,看哪個包failed了,或者直接在網上隨便找一個iris的程序go run test.go
,看報錯信息缺少哪個包。
/*test.go*/
package main
import "github.com/kataras/iris"
func main() {
app := iris.Default()
app.Handle("GET", "/", func(ctx iris.Context) {
ctx.HTML("Hello world!")
})
app.Run(iris.Addr(":8080"))
}
一般golang.org的包是無法訪問的,但好在github上都有資源,所以只需要在github上搜索缺少的包手動git clone
到golang.org/x目錄(沒有就自己創建)下即可。
除此之外github.com下的包也可能缺失,刪掉重新go get即可。
然後又出現錯誤:error未定義,翻看iris源碼發現使用了error包,而error包似乎是golang 1.13纔有的,於是更新golang到1.13。
運行go run test.go
成功會看到命令行的提示信息。
2. 使用iris框架完成本次作業
2.1 基本步驟
我的main.go如下:
package main
import (
"github.com/Tifinity/cloudgo/services"
"github.com/kataras/iris"
)
func main() {
// 獲取app
app := iris.Default()
// 日誌等級
app.Logger().SetLevel("debug")
// 運行
services.StartServices(app)
// 程序內配置服務端
app.Run(iris.Addr(":8080"), iris.WithConfiguration(iris.Configuration{
DisableInterruptHandler: false,
DisablePathCorrection: false,
先獲取app,通過iris.Default()
獲取默認app或者iris.New()
新建一個app都可以。
// 獲取app
app := iris.Default()
然後可以設置日誌等級,默認是INFO,DEBUG會在命令行窗口輸出更詳細的信息。
// 日誌等級
app.Logger().SetLevel("debug")
然後是運行端口和服務器配置,可以在程序內通過代碼配置,也可以通過TOML,YAML文件配置,配置項是抄官方文檔的,並且app初始化時已經使用了默認的配置值,無需配置也可以啓動我們的程序。
// 程序內配置服務端並運行
app.Run(iris.Addr(":8080"), iris.WithConfiguration(iris.Configuration{
DisableInterruptHandler: false,
DisablePathCorrection: false,
EnablePathEscape: false,
FireMethodNotAllowed: false,
DisableBodyConsumptionOnUnmarshal: false,
DisableAutoFireStatusCode: false,
TimeFormat: "Mon, 02 Jan 2006 15:04:05 GMT",
Charset: "UTF-8",
}))
2.2 支持靜態文件服務
只需一行代碼即可支持靜態文件的傳輸,不過前輩博客中的StaticWeb方法已經不能用了,官方文檔也還是使用的StaticWeb。
//app.StaticWeb("/static", "./static")
app.HandleDir("/static", "./static")
圖片來源於B站,·~·
2.3 支持簡單 js 訪問
簡單js訪問,比如點擊一下按鈕跳轉到另一個頁面。
/*test.js*/
// 新建窗口打開/static
function f() {
window.open("/static/img/test.webp")
}
/*hello.html*/
<input type="button" onclick="f()" value="js">
2.4 提交表單,並輸出一個表格
使用模板顯示視圖,需要先註冊,兩個參數分別是文件夾和文件類型,Reload(true)表示html更新時不用重新啓動app。
app.RegisterView(iris.HTML("./templates", ".html").Reload(true))
在hello.html中定義表單,請求方法爲POST。
<form method="POST" action="/info">
say something: <input type="text" name="Something"><br/><br/>
<input type="submit" value="submit"><br/><br/>
</form>
首先定義一個表單結構體,字段名稱需要和html中的表單字段名相同(在這裏是Something), 首字母必須大寫,使用ReadForm將表單讀取到form中,使用ViewData填充返回的html文件,第一個參數是key,第二個是value。
func StartServices(app *iris.Application) {
/*···*/
app.Post("/info", getInfo)
/*···*/
}
func getInfo(ctx iris.Context) {
form := Form{}
err := ctx.ReadForm(&form)
if err != nil {
ctx.StatusCode(iris.StatusInternalServerError)
ctx.JSON(iris.Map{
"error": "Something Wrong",
})
} else {
ctx.ViewData("something", form.Something)
ctx.View("info.html")
}
}
2.5 對 /unknown
給出開發中的提示,返回碼 5xx
使用StatusCode設置錯誤碼,然後通過WriteString或者JSON返回錯誤信息。
func unknown(ctx iris.Context) {
ctx.StatusCode(501)
ctx.JSON(iris.Map{
"error": "501 ~開發中~",
})
}
同時在特定錯誤發生時可以自定義處理函數,比如:
func StartServices(app *iris.Application) {
/*···*/
app.OnErrorCode(iris.StatusNotFound, notFound)
/*···*/
}
func notFound(ctx iris.Context) {
ctx.JSON(iris.Map{
"error": "404 Not Found",
})
/*可以返回JSON,可以返回html等等*/
}
用postman發出請求,方便看到狀態碼(右邊綠色)。