Node原生demo
1.=>创建配置模块,作用是先判断是开发环境还是生产环境,并将开发或生产环境的数据库信息和http信息分别筛开,便于选择
2.=>创建数据库模块,作用是连接数据库
3.=>创建路由模块,作用是供添加或查找路由
node_demo1过程记录 项目目录结构:
创建manager总项目目录
├ static ┬ index.html
├ css ┬...
├ js ┬...
├ upload ┬...
└ font ┬...
├ libs ┬ database.js //连接数据库
├ http.js //
└ router.js //路由
├config ┬ config.dev.js //开发配置
├ config.prod.js //生产配置
└ index.js
├
├package.json //npm init -y
└server.js
config
开发环境 config.dev.js
const path = require('path');
module.exports={
//database
DB_HOST:'localhost',
DB_PORT:,
DB_USER:'root',
DB_PASS:'',
DB_NAME:'node_sql',
//http
HTTP_PORT:,
HTTP_ROOT:path.resolve(__dirname,'../static'),
HTTP_UPLOAD:path.resolve(__dirname,'../static/upload'),
}
生产环境 config.prod.js
module.exports={
//database
DB_HOST:'211.211.211.211',
DB_PORT:,
DB_USER:'root',
DB_PASS:'',
DB_NAME:'node_sql'
}
index.js
const process = require('process'); //process。当前进程的信息,当前程序的信息
// console.log(process.env); //系统环境信息
// console.log(process.env.OS); //当前系统内核
let mode = (process.env.OS=='Windows_NT'?'dev':'prod');
// 判断是开发环境或生产环境
// console.log(mode);
module.exports={
mode,
...(mode=='dev'?require('./config.dev'):require('./config.prod'))
}
libs
数据库文件 database.js
const mysql = require('mysql');
const co = require('co-mysql');
const {DB_HOST,DB_PORT,DB_USER,DB_PASS,DB_NAME}=require('../config');
let conn = mysql.createPool({
host:DB_HOST,
port:DB_PORT,
user:DB_USER,
password:DB_PASS,
database:DB_NAME,
});
module.exports=co(conn);
http.js
const http = require('http');
const url = require('url');
const querystring = require('querystring');
const zlib = require('zlib'); //压缩请求
const fs =require('fs'); //读文件
const router = require('./router'); //路由
// const multiparty = require('multiparty');
const {Form} = require('multiparty'); //主要要用到multiparty里的Form
const {HTTP_PORT,HTTP_ROOT,HTTP_UPLOAD}=require('../config');
http.createServer((req,res)=>{
res.setHeader('content-type','application/json');
res.writeJson = function(json){
res.write(JSON.stringify(json));
}
//1.先解析数据
//2.再找路由
//1.
let {pathname,query}=url.parse(req.url,true);
if(req.method=='POST'){
if(req.headers['content-type'].startsWith('application/x-www-form-urlencoded')){
//判断头,该处为普通的POST
let arr=[];
req.on('data',buffer=>{
arr.push(buffer);
});
req.on('end',()=>{
let post =querystring.parse(Buffer.concat(arr).toString());
//2.
handle(req.method,pathname,query,post,{}); //拿到post数据,文件数据为空
})
}else{
//这是文件的POST
let form = new Form({
uploadDir:HTTP_UPLOAD //这里是上传文件的地址,
})
form.parse(req);
let post={};
let files={};
form.on('field',(name,value)=>{
post[name]=value;
});
form.on('file',(name,file)=>{
files[name]=file;
})
form.on('error',err=>{
console.log(err);
})
form.on('close',()=>{
//2.
handle(req.method,pathname,query,post,files);
})
}
}else{
//2.
handle(req.method,pathname,query,{},{}); //post和文件都为空
}
async function handle(method,url,get,post,files){
let fn = router.findRouter(method,url);
if(!fn){
//文件请求
let filepath = HTTP_ROOT+pathname;
fs.stat(filepath,(err,stat)=>{
if(err){
res.writeHeader();
res.write('NOT FOUND');
res.end();
}else{
let rs=fs.createReadStream(filepath);
let gz=zlib.createGzip();
res.on('error',()=>{
})
res.setHeader('content-encoding','gzip');
rs.pipe(gz).pipe(res);
}
})
}else{
//接口
try{
await fn(res,get,post,files);
}catch(e){
res.writeHeader();
res.write('Internal Server Error');
res.end();
}
}
}
}).listen(HTTP_PORT,()=>{
console.log(`server ${HTTP_PORT} success`);
});
路由文件 router.js
//路由表
let router={}; function addRouter(method,url,fn){
method = method.toLowerCase();
url = url.toLowerCase(); router[method] = router[method]||{}; //看method是否有东西,有则用,没有则新建一个
router[method][url] = fn;
} function findRouter(method,url){
method = method.toLowerCase();
url = url.toLowerCase(); if(!router[method]||!router[method][url]){
return null; //找不到路由
}else{
return router[method][url];
}
} module.exports={
addRouter,findRouter
};
Server.js
// const config = require('./config'); //它会自动找config目录下的index.js,因而index.js不用写
// const db = require('./libs/database');
// (async ()=>{
// let data = await db.query('SELECT * FROM usertable');
// console.log(data);
// })();
// // 上述代码主要是为了检查是开发环境或是生产环境,进而检查数据库是否连接成功
const db = require('./libs/database');
const http = require('./libs/http');
const {addRouter} = require('./libs/router');
addRouter('get','/list',async(res,get,post,files)=>{
try{
let data = await db.query(`SELECT * FROM usertable`);
res.writeJson({error:,data});
}catch(e){
res.writeJson({error:,msg:'database error'});
}
let data=await db.query(`SELECT * FROM usertable`);
res.writeJson({error:,data});
res.end();
});
addRouter('post','/add',async(res,get,post,files)=>{
let {username,password,nickname}=post;
if(!username||!password||!nickname){
res.writeJ({error:,msg:'params invaild'});
}else{
password=Number(password);
if(isNaN(password)){
res.writeJ({error:,msg:'params invaild'});
res.end();
}else{
try{
// db.query(`INSERT INTO usertable (username,password,nickname) VALUES ('{$username}','{$password}','{$nickname}')`);
//安全
await db.query('INSERT INTO usertable (username,password,nickname) VALUES(?,?,?)',[username,password,nickname]);
res.writeJson({error:,msg:'success'})
}catch(e){
res.writeJson({error:,msg:'database error'})
}
}
}
res.end();
});
addRouter('get','/del',async(res,get,post,files)=>{
res.write(get['a']+get['b']);
res.end();
});
Node原生demo的更多相关文章
- nodejs,node原生服务器搭建实例
nodejs,node原生服务器搭建实例
- 使用node-gyp编写简单的node原生模块
通过样例,让我们了解如何编写一个node的原生模块.当然,这篇文章还有一个目的,是为了方便以后编写关于node-gyp的文章,搭建初始环境. 基于node-addon-api 基于node-addon ...
- node 发送邮件demo (QQ邮箱)
nodemailer是nodejs中的邮件发送模块,本文使用的版本为2.5.0 --下载模块 npm install nodemailer npm下载模块后,在项目中引入就可以使用: var node ...
- 简单node服务器demo,麻雀虽小,五脏俱全
//本服务器要实现的功能如下: //1.静态资源服务器(能读取静态资源) //2.能接收get请求,并能处理参数 //3.能接收post请求,并能处理参数 const http = require(' ...
- Vue+Iview+Node 登录demo
1.相关组件安装 axios iview js-cookie crypto-js 2.子父组件传值.监听窗体大小改变.记住密码 .自定义组件(事件 .props) created:实例已经创建完 ...
- 瀑布流原生ajax,demo
最近听朋友们说起瀑布流挺多的,自己就去研究下了,一个简单的原生demo,分享给大家... 简单分为三个文档,有详细的注释 img:ajax.php:demo.php 其中img中放入图片 1.jpg: ...
- Node.js原生及Express方法实现注册登录原理
由于本文只是实现其原理,所以没有使用数据库,只是在js里面模拟数据库,当然是种中还是需要用数据库的. 1.node.js原生方法 ①html页面,非常简单,没有一丝美化~我们叫它user.html & ...
- 原生ajax瀑布流demo
最近听朋友们说起瀑布流挺多的,自己就去研究下了,一个简单的原生demo,分享给大家... 简单分为三个文档,有详细的注释:img:ajax.php:demo.php 其中img文件夹中放入图片 1.j ...
- 【译】使用 ndb 调试 node 应用
原文链接:Debugging Node.js Application Using ndb Google Chrome 实验室发布了一款新的 node debug 工具来提升开发者体验,本文将会全面介绍 ...
随机推荐
- EXE中释放DLL中分配的内存
在DLL中分配的内存,如果到其调用者中释放,可能会出现CRASH的情况,其原因在于: 在DLL中的Code Generation如果是采用了MT(静态加载LIBCRTD.LIB)在该库中维护了一个al ...
- laravel各种请求类
curl请求类 composer require php-curl-class/php-curl-class
- vector 与 array
vector STL中的模板数组(在堆中分配内存空间,通过new delete管理内存) 使用包涵头文件#include <vector> vector<ElmentTpye> ...
- [python之ipython] jupyter notebook在云端服务器上开启,本地访问
本地ssh到云端: ssh username@xxx.xxx.xxx.xxx -L127.0.0.1:7777:127.0.0.1:8888 把云端的8888端口映射到本地的7777端口 云端运行指令 ...
- Python基础面试题整理
基础 Python中lambda是什么意思 Python中的pass是什么意思 作为解释型语言,Python如何运行 什么是Python的单元测试 在Python中unittest是什么 如何将数字转 ...
- axios拦截器使用方法
vue中axios获取后端接口数据有时候需要在请求开始时显示loading,请求结束后隐藏loading,这时候到每次调接口时都写上有点繁琐,有时候还会漏写. 这时候axios的拦截器就起了作用,我们 ...
- Namenode服务挂
BUG修复:HDFS-13112 这两天排查了小集群Crash的问题,这里先总结下这两天排查的结果 一.查看日志 首先查看了Namenode Crash的时候的日志 (一)以下是patch hdfs- ...
- Docker+Rancher构建部署流水线
工作多年,在项目部署方面, 1:以前用ftp或者rz上传更新的,每次更新算上打包.目录切换.更新遗漏.备份.出错还原.启动等工作都得搞上一来小时甚至更长,要是多两台服务器那心都凉了: 2:后来有用sv ...
- map,实现技巧,id
cf #include<iostream> #include<cstdio> #include<algorithm> #include<vector> ...
- Grafana添加Zabbix为数据源(二)
接触过grafana的同学肯定会觉得grafana比zabbix的图像灵活好看很多,下面就让我们一起进行grafana的web界面配置 1.鼠标移动到左上角,点击Plugins,然后选择"c ...