ming_node

作者: Minglie | 来源:发表于2021-01-17 10:18 被阅读0次

ming_node

介绍

ming_node是什么

ming_node是用于快速构建web服务与接口测试的工具库,使用方法与express非常类似,并且ming_node只有一个文件,ming_node可以随用随扔而又让人不感到可惜,ming_node的web服务部分是参照express来写的.

安装

更新日志

最新稳定版本:v1.8.2
项目主页 GitHub
每个版本的更新日志 GitHub
项目地址 GitHub
npm地址 NPM

NPM

ming_node无任何第三方依赖,只是一个比较大的js文件.

# 最新稳定版
npm i ming_node

0依赖引入

https://minglie.github.io/js/ming_node.js

+async function () {
    M = await new Promise((v) => require('https').get("https://minglie.github.io/js/ming_node.js", (q) => { d = ''; q.on('data', (a) => d += a); q.on('end', () => v(eval(d))) }))
    var app = M.server();
    app.listen(8888);
    app.get("/getById", async (req, res) => {
        console.log(req.params);
        res.send("ok");
    })
}();

起步

官方指南假设你已了解关于node, commonJs, npm的初级知识。如果你没用过node不知道npm,
花点时间了解一下http://www.runoob.com/nodejs/nodejs-install-setup.html, 把node环境装上就ok了.

快速体验

下面是ming_node关于web服务的最小环境 ,如果你只对web服务感兴趣可以直接看 Web服务章节

var M = require("ming_node");
var app = M.server();
app.listen(8888);//服务在8888端口监听
app.get("/getById", (req, res) => {
    console.log(req.params);//任何形式的请求参数全部已经封装在req.params里
    res.send("ok");//响应一个"ok"字符串
})

在浏览器中输入http://localhost:8888/getById?id=5 效果如下图

image.png

token,csrf等的处理

我没有封装相关方法,但是用原生方法结合全局作用域能很容易实现,只是读请求头,设置响应头的东西,
下面是一个token 鉴权的例子

M=require("ming_node")
app=M.server()
app.listen(8888)
token="abcdefg"

app.get("/getUserById",(req,res)=>{
    console.log(req.params)
    if(req.headers["authorization"]==token){
        id=req.params.id;
        res.send(M.result("ok"));
    }else{
        res.send(M.result("无权访问"));
    }
})


SSE服务端推送消息到浏览器

服务端代码


var M=require("ming_node");

var app=M.server();
app.listen(8888);

sseApp=M.sseServer()
sseApp.listen(2000)

app.get("/getById",(req,res)=>{ 
    console.log(req.params);
    sseApp.send(JSON.stringify(req.params));
    res.send("ok");
})

或者共有Web服务端口

var M=require("ming_node");

var app=M.server();
app.listen(8888);

sseApp=M.sseServer()
//sseApp.listen(2000)

app.get("/sseServer",sseApp)

app.get("/getById",(req,res)=>{ 
    console.log(req.params);
    sseApp.send(JSON.stringify(req.params));
    res.send("ok");
})



浏览器代码

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>xxx</title>
</head>
<body>
<h1>获取服务端更新数据</h1>
<div id="result"></div>

<script>

if (window.EventSource) {
  // 创建 EventSource 对象连接服务器
  const source = new EventSource('http://localhost:2000');

  // 连接成功后会触发 open 事件
  source.addEventListener('open', () => {
    console.log('Connected');
  }, false);

  // 服务器发送信息到客户端时,如果没有 event 字段,默认会触发 message 事件
  source.addEventListener('message', e => {
    console.log(`data: ${e.data}`);
  }, false);

  // 自定义 EventHandler,在收到 event 字段为 slide 的消息时触发
  source.addEventListener('slide', e => {
    result.innerText+=e.data;
    console.log(`data: ${e.data}`); 
  }, false);

  // 连接异常时会触发 error 事件并自动重连
  source.addEventListener('error', e => {
    if (e.target.readyState === EventSource.CLOSED) {
      console.log('Disconnected');
    } else if (e.target.readyState === EventSource.CONNECTING) {
      console.log('Connecting...');
    }
  }, false);
} else {
  console.error('Your browser doesn\'t support SSE');
}

</script>

</body>
</html>

或者使用ming_mock

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>xxx</title>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script src="https://minglie.github.io/js/M_mock.js"></script>
</head>
<body>
<h1>获取服务端更新数据</h1>
<div id="result"></div>
<script>

         M.EventSource('http://localhost:2000',function(e){
            result.innerText+=e.data;
         })

</script>

</body>
</html>

效果

image.pngimage.png

前端学习环境搭建

为了方便前端学习可以使用 ming_node与ming_click搭建一个方便的环境

后端代码

var M=require("ming_node");
var app=M.server();
app.listen(8888);
app.get("/",async (req,res)=>{ 
   app.redirect("/index.html",req,res)
})
app.get("/pagelist",async (req,res)=>{ 
    //如果是linux系统应改用 M.exec("ls static")
    let s= await M.exec("dir static /b")
    res.send(M.result(s))
})

或者0依赖

+async function () {
    M = await new Promise((v) => require('https').get("https://minglie.github.io/js/ming_node.js", (q) => { d = ''; q.on('data', (a) => d += a); q.on('end', () => v(eval(d))) }))
    var app = M.server();
    app.listen(8888);
    app.get("/", async (req, res) => {
       app.redirect("/index.html", req, res)
    })

    app.get("/pagelist",async (req,res)=>{ 
        //如果是linux系统应改用 M.exec("ls static")
        let s= await M.exec("dir static /b")
        res.send(M.result(s))
    })
}();

前端代码

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>index</title>
    <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
</head>

<body>
    <div id="app">
        <h1>网页列表</h1>
        <div v-for="file in list">
            <a :href="file">{{ file }}</a> 
 

        </div>
    </div>
    <script type="text/javascript">
        new Vue({
            el: '#app',
            data() {
                return {
                    list: null
                }
            },
            mounted() {
                M_this = this;
                fetch('/pagelist').then(function (response) {
                    return response.json();
                }).then(function (response) {
                    let list = response.data.split("\n");
                    list = list.filter((d) => (d.indexOf(".html") >= 0))
                    console.log(list)
                    M_this.list = list
                });
            }

        })
    </script>
</body>
</html>

前后端代码还可以合并

+async function () {
    M = await new Promise((v) => require('https').get("https://minglie.github.io/js/ming_node.js", (q) => { d = ''; q.on('data', (a) => d += a); q.on('end', () => v(eval(d))) }))
    url = require("url");

    var app = M.server();
    app.set("views", "./")
    app.listen(8888);

    app.begin((req, res) => {
        if (req.url.includes(".html")) {
            let obj = url.parse("?" + req.url, true);
            req.url = "/" + Object.keys(obj.query)[0].slice(1)
        }
        console.log(req.url)
    })


    app.get("/pagelist", async (req, res) => {
        //如果是linux系统应改用 M.exec("ls static")
        let s = await M.exec("ls")
        res.send(M.result(s))
    })

    app.get("/", async (req, res) => {
        res.writeHead(200, { "Content-Type": "text/html;charset='utf-8'" });
        res.write(`<!DOCTYPE html>
                        <html>

                        <head>
                            <meta charset="utf-8">
                            <title>index</title>
                            <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
                        </head>

                        <body>
                            <div id="app">
                                <h1>网页列表</h1>
                                <div v-for="file in list">
                                    <a :href="file">{{ file }}</a> 
 

                                </div>
                            </div>
                            <script type="text/javascript">
                                new Vue({
                                    el: '#app',
                                    data() {
                                        return {
                                            list: null
                                        }
                                    },
                                    mounted() {
                                        M_this = this;
                                        fetch('/pagelist').then(function (response) {
                                            return response.json();
                                        }).then(function (response) {
                                            let list = response.data.split("\\n");
                                            list = list.filter((d) => (d.indexOf(".html") >= 0))
                                            console.log(list)
                                            M_this.list = list
                                        });
                                    }

                                })
                            </script>
                        </body>
                        </html>`
        );
        res.end(); /*结束响应*/
    })
}();

ming_click自动刷新浏览器

 如果需要自动刷新浏览器,可以在后端加入这两行代码,原理是用C语言找到页面的窗口句柄,模拟按下F5键

https://github.com/minglie/ming_click

var C = require('ming_click');
C.watch("./static")

其他方法

//执行一条系统命令,打印当前的TCP/IP配置的设置值
console.log(M.exec("ipconfig"))
//延时指定毫秒
M.sleep(numberMillis)
//下划线转驼峰,打印"userId"
console.log("user_id".underlineToHump())
//驼峰转下划线,打印"user_id"
console.log("userId".humpToUnderline())
//首字母变大写,打印"User"
console.log("user".firstChartoUpper())
//首字母变小写,打印"uSER"
console.log("USER".firstChartoLower())
//打印当前日期,2019-03-24
console.log(new Date().format("yyyy-MM-dd"))

其他ming_node相关

便捷的静态web服务

在含有static文件夹的目录执行下面命令,static便作为web根目录

#node
curl https://minglie.github.io/js/index.js > index.js && node index.js
#python
curl https://minglie.github.io/python/index.py > index.py && python index.py

#启动ming_mock_server
git clone https://github.com/minglie/ming_mockServer.git && cd ming_mockServer && npm i && npm run start

#curl启动ming_mockServer0
curl https://minglie.gitee.io/mingpage/static/js/ming_mockServer0.js > index.js && node index.js

当前目录静态页

curl https://minglie.gitee.io/mingpage/static/js/index_cur.js > index.js && node index.js
+async function(){
    M =await new Promise((v)=>require('https').get("https://minglie.github.io/js/ming_node.js",(q)=>{d='';q.on('data',(a)=>d+=a);q.on('end',()=>v(eval(d)))}))
  var app=M.server();
  app.set("views","./")
    app.listen(8888);
    app.get("/",async (req,res)=>{ 
       app.redirect("/index.html",req,res)
    })
}();

接口代理

/**
 POST  http://localhost:8888/axios
 {
   "url": "https://www.baidu.com/",
   "method":"get",
    "headers": {"Content-Type": "application/json"},
   "params": {
          "dd":848
    },
   "data": {
          "id":5 
    }
}
 */
function myAxios(body) {
    let bodyObj = JSON.parse(body);
    return new Promise((r, j) => {
        try {
            let getData = {}
            if (bodyObj.method == "post") {
                if (bodyObj.params) {
                    let getData = Object.keys(bodyObj.params).map(u => u + "=" + bodyObj.params[u]).join("&");
                    if (bodyObj.url.indexOf("?") > 0) {
                        getData = "&" + getData;
                    } else {
                        getData = "?" + getData;
                    }
                    bodyObj.url = bodyObj.url + getData;
                }
                M.post(bodyObj.url, r, bodyObj.data, bodyObj.headers)
            } else {
                M.get(bodyObj.url, r, bodyObj.params, bodyObj.headers)
            }
        } catch (e) {
            j(e);
        }
    });
}

app.post("/axios", async (req, res) => {
    console.log(req.body)
    let r = await myAxios(req.body)
    res.send(M.result(r));
})

写web接口最快捷的方式ming_share_edit

运行脚本, 访问 http://localhost:8888/

curl https://minglie.gitee.io/mi/i2.js > index.js && node index.js
image.pngimage.png

ming_api_mock

   因为 ming_share_edit采用txt格式存储文件,不便于编辑器查看,以及启动文件的冗余,不支持多服务文件,因此有了命令行工具 [ming_api_mock](https://www.yuque.com/docs/share/fc8547e1-e815-4e50-817c-4829e3c76442?#)

相关文章

  • ming_node

    ming_node 介绍 ming_node是什么 安装 更新日志 最新稳定版本:v1.8.2项目主页 GitHu...

网友评论

      本文标题:ming_node

      本文链接:https://www.haomeiwen.com/subject/akraaktx.html