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 工具来提升开发者体验,本文将会全面介绍 ...
随机推荐
- SQL Server孤立用戶
如何解决孤立用户问题 http://blog.csdn.net/zzl1120/article/details/7394468 SQL SERVER孤立用户问题解决方法 http://www.2cto ...
- useradd/usermod/userdel/passwd/groupadd/groupmod/groupdel/gpasswd
用户 用户系统也是通过一个文件来管理的,默认的root用户id是0, shadow文件说明 加密算法类别 $后面的数字6指定了加密算法使用的是第六种,sha512加密 增加用户,修改成同样的密码,查看 ...
- 【CUDA 基础】5.1 CUDA共享内存概述
title: [CUDA 基础]5.1 CUDA共享内存概述 categories: - CUDA - Freshman tags: - CUDA共享内存模型 - CUDA共享内存分配 - CUDA共 ...
- [Linux命令]curl命令参数详解——转载
linux curl是通过url语法在命令行下上传或下载文件的工具软件,它支持http,https,ftp,ftps,telnet等多种协议,常被用来抓取网页和监控Web服务器状态.curl命令参数介 ...
- tomcat在浏览器输入用户名和密码后报错Tomcat Manager App--403 Access Denied You are not authorized to view this page
报错截图:Tomcat Manager App--403 Access Denied You are not authorized to view this page 解决办法: 1.关闭Tomcat ...
- javafx随手记录
javafx的webview嵌套网页的时候可能会遇到一些需要允许跨域访问(禁止同源策略)的页面 那么我们在初始化的代码前加上以下代码即可 System.setProperty("sun.ne ...
- spring boot通过自定义注解和AOP拦截指定的请求
一 准备工作 1.1 添加依赖 通过spring boot创建好工程后,添加如下依赖,不然工程中无法使用切面的注解,就无法对制定的方法进行拦截 <dependency> <group ...
- iTerm2使用Profiles自动登录
http://blog.csdn.net/wandershi/article/details/75088310 1.创建Profiles文件 cd ~/.ssh/iTerm2SSH/ vi 172.1 ...
- word2vec原理与代码
目录 前言 CBOW模型与Skip-gram模型 基于Hierarchical Softmax框架的CBOW模型 基于Negative Sampling框架的CBOW模型 负采样算法 结巴分词 wor ...
- Android编译异常` Cause: duplicate entry: META-INF/MANIFEST.MF`
目录 Android编译异常Cause: duplicate entry: META-INF/MANIFEST.MF 解决方案2: 治标又治本(暂无) 解决方案1: 治标不治本(还原大法) 参考资料 ...