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 ...
- [SDOI2006]最短距离
洛谷题目链接 声明: 本篇文章只大概讲思路 原串设为$s1$,目标串设为$s2$,$n1,n2$分别为他们的长度 我们考虑$dp$,设$f[i][j]$表示$s1$中删除到了第$i$个字符,$s2$中 ...
- Codevs 1574 广义斐波那契数列(矩阵乘法)
1574 广义斐波那契数列 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 广义的斐波那契数列是指形如an=p*an-1+q* ...
- c语言if-else的效率比较
闲着没事测试下if-else的执行效率 测试环境:Mac pro i7 2.3Ghz ...编译器gcc 4.9,代码没有进行优化-O0: 测试代码:c代码1: int main(){ int n=1 ...
- Linux之GDB命令(二)
gdb命令: 前提条件:可执行文件必须包含调试信息 gcc -g gdb 文件名 –启动gdb调试 查看代码命令 当前文件: list 行号(函数名) 指定文件: list 文 ...
- 编译参数(-D)
程序中可以使用#ifdef来控制输出信息 #include<stdio.h> #define DEBUG int main() { ; ; int sum = a + b; #ifdef ...
- Windows下安装Elasticsearch6.4.1和Head,IK分词器
所需运行环境 1.安装jdk1.8(步骤略) 2.安装git(步骤略)3.安装nodejs(步骤略) 一.ElasticSearch的安装 下载elasticsearch6.4.1,将下载后的es解压 ...
- elasticsearch集群部署以及head插件安装
环境准备 elasticsearch是Java程序写的因此必须装jdk,否则使用不了. [root@openstack ~]# java -versionopenjdk version "1 ...
- 为vue3.0学点typescript, 解读高级类型
知识点摘要 本节课主要关键词为: 自动类型推断 / 类型断言 / 类型别名(type) / 映射类型(Pick/Record等...) / 条件类型(extends) / 类型推断(infer) 自动 ...
- MySQL| MySQL关键字和保留字
MySQL 5.5 Keywords and Reserved Words The following list shows the keywords and reserved words in My ...