进阶-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 访问下面地址 http://127.0.0.1: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: "模版测试"})