npm i @ghini/kitimportkitfrom"@ghini/kit/dev";快速开始,非常实用,用完就离不开的cs(console):
测试文件路径: ./test/t-cs.js
importkitfrom"@ghini/kit/dev";kit.cs();// kit.cs(0);// kit.cs(1);// kit.cs(2);// kit.cs(3);// kit.cs({// dev:{info:3},// });// kit.cs({// dev:{info:6},// err:{info:3},// log:{trace:2},// });console.log("Let's start!");console.info("info");console.debug("debug");console.warn("warn");console.error("error");console.dev("dev");node --watch ./test/t-console.js进阶用法: 尝试依序将下方注释解开
测试文件路径:./test/api/main.js
importkitfrom"@ghini/kit";kit.cs();constserver=kit.h2s();kit.h2s({allowHTTP1: false});kit.hss();kit.hs();kit.h2s(8080);server.addr("/",(gold)=>gold.json(gold));server.addr("/post","post",(gold)=>gold.raw("post only"));server.addr(/regexp/,(gold)=>gold.raw("任意包含regexp的路径 Any path that contains regexp"));console.log(server.routes);- 多路复用✅
- cookie管理✅
- 灵活的请求参数处理✅
- 可复用的参数构造✅
- 可高度自定义请求头,请求体✅
- 自动解码br,deflate,zstd,gzip压缩的响应体✅
- 自动解析json✅
测试文件路径:
./test/t-req.js
importkitfrom"@ghini/kit/dev";kit.cs({dev: {line: 3},});// 创建http https h2服务器,并设置/test路由constsarr=awaitPromise.all([kit.hs(3300),kit.hss(3301),kit.h2s(3302)]);functionfn(g){const{ query, data, cookie }=g;g.setcookie([`t=${performance.now()};max-age=3600`,"a=1;max-age=3600"]);g.json({ query, data, cookie });}sarr.forEach((s)=>{s.addr("/timetout",()=>{});s.addr("/test",fn);});// req使用示例console.log("超时(错误处理)示例===========================================");let[res,res1,res2]=awaitPromise.all([kit.req("http://localhost:3300/timetout").then((res)=>console.log(res)||res),kit.req("https://localhost:3301/timetout",{cert: false,timeout: 4000}).then((res)=>console.log(res)||res),kit.req("https://localhost:3302/timetout",{cert: false,timeout: 1000}).then((res)=>console.log(res)||res),]);console.log(res.reqbd);console.log(res1.reqbd);console.log(res2.reqbd);awaitkit.sleep(5000);console.log("method,query,body,options,headers示例===========================================");constjson={foo: "hello"};[res,res1,res2]=awaitPromise.all([res.req("/test?a=1&a=2&b=宝贝 post",{ json }).then((res)=>console.log(res)||res),res1.req("/test?a=1&a=2&b=宝贝 post",{cert: false,timeout: 4000, json }).then((res)=>console.log(res)||res),res2.req("/test?a=1&a=2&b=宝贝 post",{cert: false,timeout: 1000, json }).then((res)=>console.log(res)||res),]);awaitkit.sleep(3000);console.log("快速完全重复请求示例===========================================");res.req().then((res)=>console.log(res)||res);res1.req().then((res)=>console.log(res)||res);res2.req().then((res)=>console.log(res)||res);测试文件路径:./test/t-redis.js
测试文件路径:./test/t-basic.js./test/t-codec.js
importkitfrom"@ghini/kit/dev";kit.cs();// http1.1服务器kit.hs(3001);// http2tls服务器,兼容1.1constserver=kit.h2s(3002);// 默认路由为空,但有全局404错误处理console.log(server.routes);// 这些是预定义的路由,可以尝试一一去访问,体会其效果server.routes=kit.default_routes();// function default_routes() {// return [// ["/", "*", "*", hd_hello.bind("Ghini"), undefined, {}],// [/^\/gold/, "*", "*", hd_hello.bind("RegExp"), undefined, {}],// ["/gold", "*", "*", hd_default, undefined, {}],// ["/data", "POST", "*", hd_data, undefined, {}],// ["/error", "*", "*", hd_error, undefined, {}],// ["/stream", "*", "*", hd_stream, undefined, {}],// ["/countdata", "*", "*", (g) => g.end(g.body), hd_countdata, {}],// ];// }console.log(server.routes);server.addr(/^\/gold/,(gold)=>gold.raw("cover"));server.addr("/data","post",(gold)=>gold.json(gold));server.addr(/any/,(gold)=>{gold.respond({"content-type": "text/plain;charset=UTF-8","set-cookie":
"name=ghini;max-age=3600;path=/;httponly;secure;samesite=strict",});gold.write("你可以使用任何带有any的url访问这个路由\n");gold.end("但不包括?后面的参数,其属于param");});// 第一个函数是handle_onend,第二个函数(很少用)是handle_ondata(需要传body,多一点效果明显)server.addr("/handle_ondata",(g)=>g.end(g.body),(g,chunk,chunks)=>{// 响应头一定是在body前返回的,如果直接write会默认给响应头// gold.respond方法做过优化,不会重复给响应头g.respond({"content-type": "text/plain;charset=UTF-8",});console.log(chunk,chunks.length);// 这里我们尝试改掉原来的chunks.push(chunk); 会影响gold.body的生成// chunks.push(chunk);chunks.push(Buffer.from(chunks.length+','));g.write(`data: ${chunks.length}\n`);});console.log(server.routes);server._404=undefined;//虽然能去掉,但后台会报错server._404=()=>{};//正确不报错的去404提示server._404=(g)=>{g.err("404 not found , 自定义的404响应",404);};// 用postman之类工具,对/data进行一些测试,比如[/post](https://localhost:3002/data?a=123&中文=你好),对body的json x-www-form-urlencoded form-data的主流类型都进行了支持,轻松一键获取数据.// 我们使用最复杂的情况,form-data指定key携带多文件,和空key多文件server.addr("/data",'post',(gold)=>{gold.respond({"content-type": "text/plain;charset=UTF-8"});gold.write(JSON.stringify(gold.param)+'\n');gold.end(JSON.stringify(gold.data,0,2));});{"a":"123","中文":"你好"}
{
"vk_swiftshader_icd.json": {
"filename": "vk_swiftshader_icd.json",
"content": "{\"file_format_version\": \"1.0.0\", \"ICD\": {\"library_path\": \".\\\\vk_swiftshader.dll\", \"api_version\": \"1.0.5\"}}",
"contentType": "application/json"
},
"Squirrel-UpdateSelf.log": {
"filename": "Squirrel-UpdateSelf.log",
"content": "[15/12/24 09:23:05] info: Program: Starting Squirrel Updater: --updateSelf=C:\\Users\\pznfo\\AppData\\Local\\SquirrelTemp\\Update.exe\r\n[15/12/24 09:23:05] info: Program: About to wait for parent PID 46400\r\n[15/12/24 09:23:07] info: Program: Finished Squirrel Updater",
"contentType": "text/plain"
},
"usekey": [
{
"filename": "profile.json",
"content": "{\n\"name\": \"Postman\",\n\"company\": \"Postman\",\n\"installationOptions\": {}\n}",
"contentType": "application/json"
},
{
"filename": "icon.png",
"content": "�PNG\r\n\u001a\n+00:00���:\u0000\u0000\u0000%tEXtdate:modify\u0000IEND�B`�",
"contentType": "image/png"
}
],
"ok": "good"
}