进阶-HTTP服务
用Z1h进行HTTP服务的开发是一件非常简单的事情
启动
在命令行输入
z1h -web 30030
上例可以在30030端口开启http服务
也可以使用配置文件(解压后的conf.json文件)
z1h -conf conf.json
可以看到命令行输出了
Initing z1h...
[Zwei.Ren/Web] Running on port :30030 with 8 routers.
[Zwei.Ren/Web] You may visit at 192.168.1.2:30030
访问下面地址
可以看到
Hello World! -- ZweiRen.Web
文件结构
在本目录的datas目录下, 自动创建了一些目录和文件, 示例如下:
文件名 | 用途 |
---|---|
api | 存放了接口文件 |
assets | 可以存放一些资源文件 |
front | 一般用于存放静态前端文件 |
接口
在datas/api
目录下, 创建以.z1h
为后缀名的文件, 就可以创建一个接口
例如:
// datas/api/hello.z1h 文件
"Hello World!"
即可访问 http://127.0.0.1:30030/api/hello 看到该接口返回的数据
请求、响应
在该z1h文件内, 每次请求会有一个全局变量this
(也可以request
), 类型为*SimpleRouter
, 包含了该次http请求的所有请求信息、响应方法
// 请求内容
print(this.Method) // 请求方法, 如get、post、put、delete、options
print(this.Request.URL.String()) // 请求路径
print(this.GetGetParamMap()) // url内的参数
print(this.GetHeaders()) // 请求头信息
print(string(this.GetBody())) // 请求体
print(string(this.GetPostParams())) // 解析后的请求体
print(this.IP()) // 请求者IP
print(Object.keys(this.GetFileParams())) // 获取请求体内的文件(的字段名)
// 响应方法
this.Redirect(302, "https://z1h.org/") // 将请求302重定向
this.ServeFile("datas/favicon.ico") // 将文件响应出去
this.ResponseHeader("Content-Type", "text/plain") // 设置响应头
this.ResponseStatus(201) // 设置响应状态码
this.Tpl("hello", {title: "模版测试"}) // 响应模版文件(views/hello.tpl)
具体的使用方法详见最下方附录/SimpleRouter
路由
可以在datas/api
目录下创建目录, 再在目录下创建.z1h
文件, 即可自动讲对应路径的HTTP请求转到该接口
例如:
// datas/api/account/info.z1h 文件
`你的IP: ${this.IP()}, 浏览器: ${this.GetHeader("User-Agent")}`
就可以访问 http://127.0.0.1:30030/api/account/info 看到你的IP和浏览器UserAgent信息了
默认路径
在datas/api
目录(或子目录)下创建index.z1h
, 可以处理默认路径
例如:
// datas/api/account/index.z1h 文件
`现在的时间是 ${now()}`
可以访问 http://127.0.0.1:30030/api/account/index 来看到返回的时间信息
也可以忽略最后的index
, 直接访问 http://127.0.0.1:30030/api/account/ 看到同样的信息
404页面
在datas/api
目录(或子目录)下创建404.z1h
, 可以处理当请求地址不存在的请求
例如:
// datas/api/account/404.z1h 文件
`你走错路啦`
可以访问 http://127.0.0.1:30030/api/account/xxx 来看到404消息
assets资源
assets
目录适合存放一些静态资源, 例如jQuery.js
等
例如, 把图片复制到datas/assets/logo.png
, 就可以通过 http://127.0.0.1:30030/assets/logo.png 获取到图片了.
试试将一个js文件放进去, 然后放一个html文件引用它
front
用于部署VUE
等前端框架
- 首先确定是通过
z1h -conf 配置文件
的方式启动的 - 配置文件内的"key"对应的内容不为空, 为更新前端的密钥, 且该行没有被注释
- 导出dist目录(如使用
npm run build
) - 将dist目录压缩成zip文件
- 打开 http://127.0.0.1:30030/vueupdate
- 上传dist.zip、输入密钥、确定
现在可以在 http://127.0.0.1:30030/ 看到你部署的项目了
附录
SimpleRouter
结构体
名称 | 类型 | 描述 | 示例 |
---|---|---|---|
Method | string | 请求方法(小写) | if(this.method!='post')panic("Post Only!") |
DisableGZip | bool | 是否尝试将结果gzip压缩 | this.DisableGZip=false // 确保不压缩 |
Writer | ResponseWriter | 包含Write、WriteHeader、Header方法 | this.Writer.Write(bytearray("nihao")) |
Request | *net/http.Request | Go标准库结构体 | this.Request.URL.String() |
获取请求内容相关的方法
名称 | 描述 | 参数 | 返回值 | 示例 |
---|---|---|---|---|
IP | 获取请求者IP | - | string | |
GetGetParamMap | 获取url内的所有query参数 | - | map[string]string | |
GetGetParam | 获取url内的某个query参数 | string 字段名 | string 字段值 | if(this.GetGetParam("name")=="admin")return `管理员你好` |
GetGetIntParam | 获取url内的某个query整型参数 | string 字段名, int 默认值 | int 参数值 | |
GetHeaders | 获取请求内的全部头信息 | - | map[string][]string | |
GetHeader | 获取请求内的某个头信息 | string 头key | string 头value | if(this.GetHeader("User-Agent").contains("android")) return `安卓用户你好` |
GetBody | 获取请求体原文 | - | []byte | return `请求体长度${len(this.GetBody())}` |
GetPostParams | 获取反序列化后的的请求体内容 | - | map | |
GetPostParam | 获取请求体参数 | string 字段名 | 字段值 | |
GetFileParams | 获取form提交的文件 | - | map[string]*MultipartFileData | |
GetFileParam | 获取form提交的一个文件 | string 字段名 | *MultipartFileData |
响应相关的方法
名称 | 描述 | 参数 | 返回值 | 示例 |
---|---|---|---|---|
Redirect | 重定向 | int 状态码, string 链接地址 | - | this.Redirect(302,"https://z1h.org") |
ServeFile | 响应文件 | string文件路径 | - | this.ServeFile("datas/favicon.ico") |
ResponseHeader | 设置响应头 | string 头部key, string 头部value | - | this.ResponseHeader("Content-Type", "text/plain") |
ResponseStatus | 设置响应状态码 | int 状态码 | - | this.ResponseStatus(201) |
Tpl | 响应模版文件 | string 模版名, 模版填充内容, string 子模版… | - | this.Tpl("hello", {title: "模版测试"}) |