1.=>创建配置模块,作用是先判断是开发环境还是生产环境,并将开发或生产环境的数据库信息和http信息分别筛开,便于选择

2.=>创建数据库模块,作用是连接数据库

3.=>创建路由模块,作用是供添加或查找路由

  1. node_demo1过程记录
  2.  
  3. 项目目录结构:
  4. 创建manager总项目目录
  5. static index.html
  6. css ┬...
  7. js ┬...
  8. upload ┬...
  9. font ┬...
  10. libs database.js //连接数据库
  11. http.js //
  12. router.js //路由
  13. config config.dev.js //开发配置
  14. config.prod.js //生产配置
  15. index.js

  16. package.json   //npm init -y  
  17. server.js

config

开发环境  config.dev.js

  1. const path = require('path');
  2.  
  3. module.exports={
  4. //database
  5. DB_HOST:'localhost',
  6. DB_PORT:,
  7. DB_USER:'root',
  8. DB_PASS:'',
  9. DB_NAME:'node_sql',
  10.  
  11. //http
  12. HTTP_PORT:,
  13. HTTP_ROOT:path.resolve(__dirname,'../static'),
  14. HTTP_UPLOAD:path.resolve(__dirname,'../static/upload'),
  15. }

生产环境  config.prod.js

  1. module.exports={
  2. //database
  3. DB_HOST:'211.211.211.211',
  4. DB_PORT:,
  5. DB_USER:'root',
  6. DB_PASS:'',
  7. DB_NAME:'node_sql'
  8. }

index.js

  1. const process = require('process'); //process。当前进程的信息,当前程序的信息
  2.  
  3. // console.log(process.env); //系统环境信息
  4. // console.log(process.env.OS); //当前系统内核
  5.  
  6. let mode = (process.env.OS=='Windows_NT'?'dev':'prod');
  7. // 判断是开发环境或生产环境
  8. // console.log(mode);
  9.  
  10. module.exports={
  11. mode,
  12. ...(mode=='dev'?require('./config.dev'):require('./config.prod'))
  13. }

libs

数据库文件  database.js

  1. const mysql = require('mysql');
  2. const co = require('co-mysql');
  3. const {DB_HOST,DB_PORT,DB_USER,DB_PASS,DB_NAME}=require('../config');
  4.  
  5. let conn = mysql.createPool({
  6. host:DB_HOST,
  7. port:DB_PORT,
  8. user:DB_USER,
  9. password:DB_PASS,
  10. database:DB_NAME,
  11. });
  12.  
  13. module.exports=co(conn);

http.js

  1. const http = require('http');
  2. const url = require('url');
  3. const querystring = require('querystring');
  4. const zlib = require('zlib'); //压缩请求
  5. const fs =require('fs'); //读文件
  6. const router = require('./router'); //路由
  7. // const multiparty = require('multiparty');
  8. const {Form} = require('multiparty'); //主要要用到multiparty里的Form
  9. const {HTTP_PORT,HTTP_ROOT,HTTP_UPLOAD}=require('../config');
  10.  
  11. http.createServer((req,res)=>{
  12. res.setHeader('content-type','application/json');
  13. res.writeJson = function(json){
  14. res.write(JSON.stringify(json));
  15. }
  16.  
  17. //1.先解析数据
  18. //2.再找路由
  19.  
  20. //1.
  21. let {pathname,query}=url.parse(req.url,true);
  22.  
  23. if(req.method=='POST'){
  24. if(req.headers['content-type'].startsWith('application/x-www-form-urlencoded')){
  25. //判断头,该处为普通的POST
  26. let arr=[];
  27. req.on('data',buffer=>{
  28. arr.push(buffer);
  29. });
  30. req.on('end',()=>{
  31. let post =querystring.parse(Buffer.concat(arr).toString());
  32. //2.
  33. handle(req.method,pathname,query,post,{}); //拿到post数据,文件数据为空
  34. })
  35. }else{
  36. //这是文件的POST
  37. let form = new Form({
  38. uploadDir:HTTP_UPLOAD //这里是上传文件的地址,
  39. })
  40. form.parse(req);
  41. let post={};
  42. let files={};
  43. form.on('field',(name,value)=>{
  44. post[name]=value;
  45. });
  46. form.on('file',(name,file)=>{
  47. files[name]=file;
  48. })
  49. form.on('error',err=>{
  50. console.log(err);
  51. })
  52. form.on('close',()=>{
  53. //2.
  54. handle(req.method,pathname,query,post,files);
  55. })
  56. }
  57. }else{
  58. //2.
  59. handle(req.method,pathname,query,{},{}); //post和文件都为空
  60. }
  61.  
  62. async function handle(method,url,get,post,files){
  63. let fn = router.findRouter(method,url);
  64.  
  65. if(!fn){
  66. //文件请求
  67. let filepath = HTTP_ROOT+pathname;
  68. fs.stat(filepath,(err,stat)=>{
  69. if(err){
  70. res.writeHeader();
  71. res.write('NOT FOUND');
  72. res.end();
  73. }else{
  74. let rs=fs.createReadStream(filepath);
  75. let gz=zlib.createGzip();
  76. res.on('error',()=>{
  77.  
  78. })
  79. res.setHeader('content-encoding','gzip');
  80. rs.pipe(gz).pipe(res);
  81. }
  82. })
  83. }else{
  84. //接口
  85. try{
  86. await fn(res,get,post,files);
  87. }catch(e){
  88. res.writeHeader();
  89. res.write('Internal Server Error');
  90. res.end();
  91. }
  92. }
  93. }
  94.  
  95. }).listen(HTTP_PORT,()=>{
  96. console.log(`server ${HTTP_PORT} success`);
  97. });

路由文件  router.js

  1. //路由表
  2. let router={};
  3.  
  4. function addRouter(method,url,fn){
  5. method = method.toLowerCase();
  6. url = url.toLowerCase();
  7.  
  8. router[method] = router[method]||{}; //看method是否有东西,有则用,没有则新建一个
  9. router[method][url] = fn;
  10. }
  11.  
  12. function findRouter(method,url){
  13. method = method.toLowerCase();
  14. url = url.toLowerCase();
  15.  
  16. if(!router[method]||!router[method][url]){
  17. return null; //找不到路由
  18. }else{
  19. return router[method][url];
  20. }
  21. }
  22.  
  23. module.exports={
  24. addRouter,findRouter
  25. };

Server.js

  1. // const config = require('./config'); //它会自动找config目录下的index.js,因而index.js不用写
  2. // const db = require('./libs/database');
  3.  
  4. // (async ()=>{
  5. // let data = await db.query('SELECT * FROM usertable');
  6.  
  7. // console.log(data);
  8. // })();
  9. // // 上述代码主要是为了检查是开发环境或是生产环境,进而检查数据库是否连接成功
  10.  
  11. const db = require('./libs/database');
  12. const http = require('./libs/http');
  13. const {addRouter} = require('./libs/router');
  14.  
  15. addRouter('get','/list',async(res,get,post,files)=>{
  16. try{
  17. let data = await db.query(`SELECT * FROM usertable`);
  18. res.writeJson({error:,data});
  19. }catch(e){
  20. res.writeJson({error:,msg:'database error'});
  21. }
  22.  
  23. let data=await db.query(`SELECT * FROM usertable`);
  24. res.writeJson({error:,data});
  25. res.end();
  26. });
  27.  
  28. addRouter('post','/add',async(res,get,post,files)=>{
  29. let {username,password,nickname}=post;
  30. if(!username||!password||!nickname){
  31. res.writeJ({error:,msg:'params invaild'});
  32. }else{
  33. password=Number(password);
  34. if(isNaN(password)){
  35. res.writeJ({error:,msg:'params invaild'});
  36. res.end();
  37. }else{
  38. try{
  39. // db.query(`INSERT INTO usertable (username,password,nickname) VALUES ('{$username}','{$password}','{$nickname}')`);
  40. //安全
  41. await db.query('INSERT INTO usertable (username,password,nickname) VALUES(?,?,?)',[username,password,nickname]);
  42. res.writeJson({error:,msg:'success'})
  43. }catch(e){
  44. res.writeJson({error:,msg:'database error'})
  45. }
  46. }
  47. }
  48. res.end();
  49. });
  50.  
  51. addRouter('get','/del',async(res,get,post,files)=>{
  52. res.write(get['a']+get['b']);
  53. res.end();
  54. });

Node原生demo的更多相关文章

  1. nodejs,node原生服务器搭建实例

    nodejs,node原生服务器搭建实例

  2. 使用node-gyp编写简单的node原生模块

    通过样例,让我们了解如何编写一个node的原生模块.当然,这篇文章还有一个目的,是为了方便以后编写关于node-gyp的文章,搭建初始环境. 基于node-addon-api 基于node-addon ...

  3. node 发送邮件demo (QQ邮箱)

    nodemailer是nodejs中的邮件发送模块,本文使用的版本为2.5.0 --下载模块 npm install nodemailer npm下载模块后,在项目中引入就可以使用: var node ...

  4. 简单node服务器demo,麻雀虽小,五脏俱全

    //本服务器要实现的功能如下: //1.静态资源服务器(能读取静态资源) //2.能接收get请求,并能处理参数 //3.能接收post请求,并能处理参数 const http = require(' ...

  5. Vue+Iview+Node 登录demo

    1.相关组件安装 axios  iview  js-cookie  crypto-js 2.子父组件传值.监听窗体大小改变.记住密码 .自定义组件(事件 .props) created:实例已经创建完 ...

  6. 瀑布流原生ajax,demo

    最近听朋友们说起瀑布流挺多的,自己就去研究下了,一个简单的原生demo,分享给大家... 简单分为三个文档,有详细的注释 img:ajax.php:demo.php 其中img中放入图片 1.jpg: ...

  7. Node.js原生及Express方法实现注册登录原理

    由于本文只是实现其原理,所以没有使用数据库,只是在js里面模拟数据库,当然是种中还是需要用数据库的. 1.node.js原生方法 ①html页面,非常简单,没有一丝美化~我们叫它user.html & ...

  8. 原生ajax瀑布流demo

    最近听朋友们说起瀑布流挺多的,自己就去研究下了,一个简单的原生demo,分享给大家... 简单分为三个文档,有详细的注释:img:ajax.php:demo.php 其中img文件夹中放入图片 1.j ...

  9. 【译】使用 ndb 调试 node 应用

    原文链接:Debugging Node.js Application Using ndb Google Chrome 实验室发布了一款新的 node debug 工具来提升开发者体验,本文将会全面介绍 ...

随机推荐

  1. WebService如何封装XML请求 以及解析接口返回的XML

    原 WebService如何封装XML请求 以及解析接口返回的XML 置顶 2019年08月16日 15:00:47 童子泛舟 阅读数 28 标签: XML解析WebService第三方API 更多 ...

  2. 【线性代数】3-2:零空间(Nullspace)

    title: [线性代数]3-2:零空间(Nullspace) categories: Mathematic Linear Algebra keywords: Nullspace Pivot Colu ...

  3. [pytorch] PyTorch Hook

      PyTorch Hook¶ 为什么要引入hook? -> hook可以做什么? 都有哪些hook? 如何使用hook?   1. 为什么引入hook?¶ 参考:Pytorch中autogra ...

  4. 2017 ZSTU寒假排位赛 #5

    题目链接:https://vjudge.net/contest/148901#overview. A题,排序以后xjbg即可. B题,弄个数组记录当前列是不是删除以及当前行是不是已经大于下一行然后乱搞 ...

  5. [CSP-S模拟测试]:C(倍增+数学)

    题目传送门(内部题152) 输入格式 第一行两个整数$N,Q$. 接下来一行$N$个整数,第$i$个为$a_i$. 接下来的$N-1$行,每行两个整数$u,v$.表示$u,v$之间有一条边. 接下来的 ...

  6. axios中出现两次请求,OPTIONS请求和GET请求

    在项目中发现ajax中出现两次请求,OPTIONS请求和GET请求 查看到浏览器NetWork有两次请求,请求url一样: 查找原因是浏览器对简单跨域请求和复杂跨域请求的处理区别. XMLHttpRe ...

  7. 黑马vue---17、vue中通过属性绑定绑定style行内样式

    黑马vue---17.vue中通过属性绑定绑定style行内样式 一.总结 一句话总结: 如果属性名中带有短线必须加引号,比如: h1StyleObj: { color: 'red', 'font-s ...

  8. LC 638. Shopping Offers

    In LeetCode Store, there are some kinds of items to sell. Each item has a price. However, there are ...

  9. 使用Pull解析器生成XML文件

    有些时候,我们需要生成一个XML文件,生成XML文件的方法有很多,如:可以只使用一个StringBuilder组拼XML内容,然后把内容写入到文件中:或者使用DOM API生成XML文件,或者也可以使 ...

  10. Java之加密算法

    加密算法主要分为对称加密.非对称加密.Hash加密. 一.何为对称加密? 对称加密是指对称密码编码技术,它的特点是文件加密和解密使用相同的密钥加密. 对称机密的密钥一般小于256bit.因为就密钥而言 ...