node.js

node.js

在node平台上执行js代码

1.编写js代码,保存文件的扩展名为js
2> 在命令行窗口中,输入命令:node 文件名.js

两个js文件调用

2.js调用1.js,命令窗口执行node 2.js

// 文件1.js
module.exports = {
    函数名1:function(){
        函数体
        return 0;
    },
    函数名2:function(参数){
        函数体2
        return 0;
    }
}

// 文件2.js
var funcs = require('./1');

funcs.函数名1();
funcs.函数名2(参数);

在nodejs平台上,定义一个funcs的模块,在模块中有2个函数,一个函数使用"*"打印直角三角形图案,另一个函数用于计算从1+2+…+max的和,其中max是函数的形参。并且模块中导出这2个函数。在app.js中导入funcs模块,调用这2个函数。

// 1.js
module.exports = {
    printTriangle:function(){
        var a = '';
        for(var i=0;i<5;i++){
            a = '';
            for(var j=0;j<i;j++){
                a = a+'*';
            }
            console.log(a);
        }
    },
    cou:function(max){
        var i = 1;
        var all=0;
        for(;i<=max;i++){
            all = all+i;
        }
        return all;
    }
}

// 2.js
var funcs = require('./1');
funcs.printTriangle();
console.log(funcs.cou(100));
es6新语法
声明变量:const 声明常量,不能修改
		let 声明的变量具有块的,可修改
<body>
    <script>
        const a=10;
        // a++;  // 错误,const定义的a的值不能修改
        let b=10;
        console.log(++b); // 11
    
        for(var i=0;i<10;i++){
            let cmt = 10;  // 在块中使用let声明的变量具有块的作用,var没有块作用域
            cnt++;
        }
        console.log(cnt); // 不存在,cnt值只存在于for循环中
    </script>
</body>

声明函数定义可以使用箭头函数:(形参列表)=>{函数体}

<body>
    <script>
        var getSum = (max)=>{
            var sum=0;
            for(var i=01;i<=max;i++){
                sum += i;
            }
            return sum;
        }
        console.log(getSum(100));
    </script>
</body>

简化书写规则:
只有一个形参,小括号可以省略

<body>
    <script>
        var getSum = max=>{
            var sum=0;
            for(var i=1;i<=max;i++){
                sum += i;
            }
            return sum;
        }
        console.log(getSum(100));
    </script>
</body>

当函数体中只有一条返回语句,大括号和return关键字可以省略

<body>
    <script>
        var getResult = x => x*x; // 函数体
        console.log(getResult(2));
    </script>
</body>

数组排序

<body>
    <script>
        var nums = [10,40,20,30];
        nums.sort(function(a,b){
            return (a-b); // 升序排序
            //return (b-a); // 降序排序
        });
        // nums.sort((a,b)=>a-b)  // 等于上面函数
        console.log(nums);
    </script>
</body>

模块

fs模块 文件操作模块

使用文件模块来读取文件的内容

path模块就是路径模块

__dirname:记录了当前可执行程序所在的路径
path.join(路径的各部分):合并成完整路径

读 txt 文件

注意文件坐在位置,我的位置是E:\\code\\JS,文件名是a.txt

//使用文件模块来读取文件的内容
//导入文件系统模块
const fs = require('fs');
//导入路径模块
const path = require('path');

//err记录了读文件过程中发生的错误,
//data保存读取文件的内容
var fname = 'E:\\code\\JS';
console.log( __dirname);
fs.readFile(path.join(fname,'a.txt'),(err,data)=>{
     if(err){
         //发生了错误,就打印错误的原因
         console.log(err.message);
         return;
     }
     //没有错误,就打印文件的内容
     console.log(data.toString());// toString转字符串
});
console.log('程序结束');
写 txt 文件
const fs = require('fs');

var info="good morning";
//writeFile函数就是将内容写入到文件中,覆盖掉文件中原有内容
//第一个参数就是目标文件的文件名(带路径)
//第二个参数就是需要写入文件的内容
//第三个参数就是回调函数
fs.writeFile('./a.txt',info,err=>{
    if(err){
        console.log(err.message);
        return;
    }
    console.log('写入成功');
});

http 系统模块

静态服务器

http对象的方法
createServer() :创建服务器
listen(端口号):监听端口号,启动服务器

服务器:
on():订阅事件处理函数
req对象:请求对象,封装了请求数据包中的数据
req.url: 请求的页面的地址
res对象:响应对象,记录了服务器需要发送给浏览器的数据
res.end([data]): 如果有data实参,将data数据发送到浏览器中; 结束响应
res.writeHead(状态码,{属性名:属性值 }):在响应报文的报文头添加属性
res.write(内容):向浏览器中输出内容

url系统模块:进行url地址处理

url.parse(地址,true):将地址解析成一个对象
pathname: 字符串格式的具体的地址
query:就是get方式提交的数据:{数据名1:数据1,数据名2:数据2,…}

在vscode上编写如下代码保存,在该文件目录下输入cmd进入(该文件目录下的cmd界面)(要退出目前的cmd按Ctrl+C),输入node 1.js,再在浏览器输入localhost:8080进入,出现目标页面

hi,user!!!

//导入http系统模块
const http = require('http');

//调用http对象的方法创建web服务器
var app = http.createServer();
//编写请求处理函数
//req:请求对象,记录浏览器发出请求数据包中的数据
//res:响应对象,记录服务器处理的结果,响应对象中的内容最终要发送给浏览器
app.on('request',function(req,res){
    res.write('<h1>hi,user!!!</h1>');  //进入后的界面
    res.end();
})   
//服务器监听端口
app.listen(8080,function(){
    console.log('服务器已经启动,请访问http://localhost:8080 地址');
})
状态码解释
200成功
302重定向
404请求资源找不到
500服务器端代码出错

浏览器向服务器发送数据

get方式:url?数据名1=数据1&数据名2=数据2&...
http://localhost:8080/test.html?uname=Rose&salary=6000
post方式:在请求报文主体中回附带数据,
数据格式:数据名1=数据1&数据名2=数据2&...
{数据名1:数据1,数据名2:数据2,...}

接收浏览器提交的数据

get方式:let {query}=url.parse(req.url,true);query中就是get方式提交到服务器的数据

post方式:

  var  data = '';//声明变量用来保存提交的数据,赋初始值为''
  //订阅请求对象的data事件和end事件的事件处理函数
  req.on('data',(chunk)=>{
      //将接收到数据chunk连接到data变量中
      data += chunk;
  })
  req.on('end',(chunk)=>{
      //处理接收到的数据
      querystring.parse(data);//将接收到的数据转换成为json格式
  })

请求服务器端的静态页面

//建立一个服务器:http系统模块
//1 导入http模块
const http = require('http');
// 导入地址处理模块 url
const url = require('url');
// 导入路径处理模块 path
const path = require('path');
// 导入文件和文件夹操作的系统模块 fs
const fs = require('fs');

//2 调用http对象的方法创建服务器
let app = http.createServer();

//3 订阅请求到达事件的处理函数
app.on('request',(req,res)=>{
   // 1 获取请求地址中的文件名
   const {pathname} = url.parse(req.url);
   console.log(pathname);
   // 2 拼接页面文件名的绝对路径,屏蔽掉网站图标的请求
   if(!pathname.endsWith('.ico')){
       var fname = path.join(__dirname,'static',pathname);
       // 3 读取文件的内容,发送给浏览器
       fs.readFile(fname,(err,data)=>{
           //如果读文件过程中发生了错误,发回404响应
           if(err){
               res.writeHead(404,{
                   'content-type':'text/html'
               });
               res.write('error');
               res.write(err.message);
               res.end();
           }else{
               res.end(data);
           }
       })
   }else{
      res.end('<h1>OK</h1>');  
   }
})
//4 监听端口号
app.listen(8080,()=>{
    console.log('服务器已经在8080端口等待浏览器的请求...');
})
const http=require('http');
const url =require('url');
const path = require('path');
const fs = require('fs');

let app = http.createServer();
app.on('request',(req,res)=>{
   let {pathname,query} = url.parse(req.url,true);
   if(!pathname.endsWith('.ico')){
       if(query){
           //如果有提交数据,则在控制台上打印数据
           console.log(query);
       }
       var fname = path.join(__dirname,'static',pathname);
       fs.readFile(fname,(err,data)=>{
           if(err){
               res.writeHead(404,{'content-type':'text/html'});
               res.write(err.message);
               res.end();
           }else{
               res.end(data);
           }
       })
   }
});
app.listen(8080,()=>{
    console.log('服务器已经启动...')
})
const http=require('http');
const url =require('url');
const path = require('path');
const fs = require('fs');
const querystring = require('querystring');

let app = http.createServer();
app.on('request',(req,res)=>{
   let {pathname,query} = url.parse(req.url,true);
   if(!pathname.endsWith('.ico')){
       //获取post方式提交的数据
       var result='';//保存提交数据的变量
       //请求对象监听2个事件: data事件,有post方式提交的数据到达服务器
       //                  end 事件,post方式提交的数据已经全部到达
       req.on('data',(chunk)=>{           
           result += chunk;//将本次接收到的数据连接到result变量
       });
       req.on('end',()=>{        
           console.log(querystring.parse(result));
       })
       var fname = path.join(__dirname,'static',pathname);
       fs.readFile(fname,(err,data)=>{
           if(err){
               res.writeHead(404,{'content-type':'text/html'});
               res.write(err.message);
               res.end();
           }else{
               res.end(data);
           }
       })
   }
});
app.listen(8080,()=>{
    console.log('服务器已经启动...')
})

使用nodejs编写动态网站,实现用户注册功能:
地址为/reg,服务器发回有用户注册表单的页面
地址为/doReg,服务器接收提交的用户数据,发回注册成功的提示信息

先进入该目录下的cmd界面,输入node 1.js,浏览器浏览localhost:8080/reglocalhost:8080/doReg
1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="/doReg" method="post"><!--action 属性用来指定表单提交数据时所指向的地址-->
        <p>Account:<input type="text" name="acc"value=""></p>
        <p>Password:<input type="password" name="pwd"  value=""></p>
        <p><input type="submit" name="login" value="login"></p>
    </form>
</body>
</html>

1.js

//web
const http = require('http');
const url = require('url');
const path = require('path')
const fs = require('fs')
const querystring = require('querystring');

let app = http.createServer();
app.on('request',(req,res)=>{
    //处理多个请求地址,不同的地址有不同的处理方式
    // /reg:打开注册页面,静态页面:1>编写html页面代码 2>读取文件内容发给浏览器
    // /doReg:接收注册的账号和密码等等数据,提示注册成功
    const{pathname}=url.parse(req.url,true);
    switch(pathname){
        case '/reg':
            let fname = path.join(__dirname,'1.html');
            fs.readFile(fname,(err,data)=>{
                if(err){
                    res.end('<h1>ERROR</h1>');
                }else{
                    res.end(data);
                }
            })
            break;
        case '/doReg':
            var data='';
            req.on('data',(chunk)=>{
                data += chunk;
            });
            req.on('end',()=>{
                let obj = querystring.parse(data);
                console.log(obj);
                res.end('<h1>regist success'+obj.acc+'</h1>');
            });
            break;
    }
});
app.listen(8080,()=>{
    console.log('已启动');
})

浏览器端请求静态资源,如css,js,jpg图像等,服务器返回相关的资源文件

先进入该目录下的cmd界面,输入node 1.js,浏览器浏览localhost:8080/1.htmllocalhost:8080/a.jpeg
1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="/doReg" method="post"><!--action 属性用来指定表单提交数据时所指向的地址-->
        <p>Account:<input type="text" name="acc"value=""></p>
        <p>Password:<input type="password" name="pwd"  value=""></p>
        <p><input type="submit" name="login" value="login"></p>
    </form>
</body>
</html>

1.js

const http = require('http');
const url = require('url');
const path = require('path')
const fs = require('fs')
const querystring = require('querystring');

let app = http.createServer();
app.on('request',(req,res)=>{
    const{pathname}=url.parse(req.url,true);
    switch(pathname){
        case '/1.html':
            let fname = path.join(__dirname,'1.html');
            fs.readFile(fname,(err,data)=>{
                if(err){
                    res.end('<h1>ERROR</h1>');
                }else{
                    res.end(data);
                }
            })
            break;
        case '/a.jpeg':
            let fname1 = path.join(__dirname,'a.jpeg');
            fs.readFile(fname1,(err,data)=>{
                if(err){
                    res.end('<h1>ERROR</h1>');
                }else{
                    res.end(data);
                }
            })
            break;
    }
});
app.listen(8080,()=>{
    console.log('已启动');
})

Express

下载安装exprtss-generator:用于生成npm install express-generator -g生成的代码结构

app.js:入口
public文件夹:静态资源文件夹,保存html页面文件,css文件,js文件,图片文件等资源文件
views文件夹:模块文件夹,保存模块文件
routes文件夹:路由文件夹,保存路由文件f

创建项目

npm i art-template -S
npm i express-art-template -S
npm i body-parser -S
npm i session -S

1.创建项目文件夹
2.进入项目文件夹,创建配置文件package.json:npm init -y
3.使用框架系统:express
4.安装依赖的中间件:npm install
5.启动项目:npm start
注::后的代码都是在该项目文件内的cmd里输入

在项目中使用模板引擎输出带有动态数据的页面
express-art-template
在目标文件下输入npm i -S art-templatenpm i -S express-art-template执行

启动开发工具,打开项目,打开app.js,在app.js中配置模板引擎

// 导入art-tempate模板引擎
const template = require('art-template');

// 告诉express框架模板文件所在的位置
app.set('views', path.join(__dirname, 'views'));
// 告诉express框架模板的默认后缀是什么
app.set('view engine', 'art');
// 当渲染后缀为art的模板时 所使用的模板引擎是什么
app.engine('art', require('express-art-template'));
模板语法

{{变量名}} :在页面中输出变量的值
{{if(条件表达式)}}…{{/if}}:按条件输出
{{each 变量}}…{{/each}}:遍历变量中的各个元素进行循环
$value就是遍历的一个元素 $index:遍历出来的元素的下标

1> 在views文件夹下编写模板文件:*.art
2>在路由文件中渲染模板文件:res.render(模板文件名,{数据名:数据})

制作商品管理功能:商品列表、新增商品、删除商品,模块

1> 设计路由:routes/goods.js:处理商品模块的全部路由,也就是说,请求商品的任何功能由goods.js中的代码来进行处理
2>具体功能的设计:
/:商品列表, 逻辑:找到所有的商品数据;将商品数据渲染到模板文件

商品数据放在全局变量,

/delete/100:商品删除,逻辑:获取要删除商品的编号,是请求地址中的id值
params,删除商品数据,重定向到列表页面

res.redirect(‘地址’) :重定向到指定地址

新增商品:
进入新增商品的页面:点击“新增”按钮或者超链接,进入页面
页面跳转,地址设置,选择渲染模板文件()

处理新商品数据:路由的处理代码的逻辑,
1>接收post方式提交的数据 :中间件 body-parser
1.1> 安装 npm i body-parser -S
1.2> 导入
const bodyParser =require(‘body-parser’);
配置使用
// 解析 application/json
app.use(bodyParser.json());
// 解析 application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended:true}));
到req.body属性中获取数据就ok了
2> 创建新商品对象
3> 将新商品对象数据保存

==========================================================

修改商品:进入修改页面(包含表单),处理修改后的商品数据

==========================================================

用户登录功能:

进入登录页面
验证输入的用户和密码,显示验证的结果:成功了,进入商品列表页面,失败了,重新登录

路由设计: /login: 进入登录页面
1> 模板文件:views/login.art
2> 添加进入登录页面的路由
/doLogin:处理登录用户数据
添加处理登录数据的路由,逻辑:
接收数据
查找(在模拟数据中查找)

在项目中有些页面是需要登录成功后才可以进入的。
比如:商品新增页面需要登录用户才可进入
​ 在进入新增商品页面代码中添加逻辑:检查是否是登录用户,不是的话,跳转到登录页面强制用户登录。

服务器端的状态管理技术:
1> 服务器端工作在HTTP协议上,所以天生就是无状态的
2> 有的场景中需要状态:比如:购物车,
3> 状态管理的技术:Cookie :在浏览器端开文件记录浏览器自己的数据;减轻了服务器的负担;用户可以在浏览器端修改数据;数据安全性比较差;
Session:在服务器端的内存中记录浏览器端的数据;数据安全性得到保障;增加了服务器的负担

Express框架下使用cookie-parser中间件进行cookie编程
1> 下载安装:npm i cookie-parser -S
2> 配置使用cookie-parser进行cookie编程
3> 向cookie中读写数据

在同一个网站的多个页面中可以通过cookie共享数据

Express使用express-session中间件进行session状态管理
1>下载安装 npm i express-session -S
2> 在app.js中配置使用expression-session
app.use(session({
secret: ‘keyboard cat’,
resave: true, saveUninitialized: true
}));
3> 在session中读写数据
req.session.数据名称
req.session.数据名称=值

session会话变量:在一次会话中有效

===============================================================课堂练习:

在express框架下,编写学生管理的功能:学生的增删改查。
合并新增和修改

设计路由:
/edit/:id :进入修改页面
/doEdit: 处理提交的修改数据

修改
进入修改页面(包含输入数据的表单)
逻辑:根据id找到需要修改的数据;渲染模板文件,传递找到的需要修改的数据;处理修改后的数据

扩展的考虑:新增和修改多数的是一样,有少量的区别
能不能合并?合并
/change/:id :进入新增和修改表单页面的地址
/save :处理新增和修改数据的地址
如果是数据库保存数据:没有id就是新增
判断模拟数据中有没有商品,有是修改

请求

请求用途
get请求显示数据浏览器浏览
post增加数据postman浏览
put主要用于修改用户postman浏览
delete主要用于删除用户postman浏览
注:post、put、delete在浏览器中浏览不出来,要在postman软件中浏览

配置路由

get请求

可在浏览器中浏览

const express = require('express')
const app=express()

// localhost:3000
app.get("/",(req,res)=>{
    res.send('你好 express')
});
// localhost:3000/article
app.get("/article",(req,res)=>{
    res.send('新闻页面')
});
// localhost:3000/login
app.get("/login",(req,res)=>{
  res.send('登入')
});
// localhost:3000/register
app.get("/register",(req,res)=>{
  res.send('注册页面')
});

app.listen(3000,()=>{
  console.log('已启动');
});
post请求

浏览器无法浏览,需在postman软件浏览

// localhost:3000/doLogin
app.get("/doLogin",(req,res)=>{
  console.log('执行登录');
  res.send('执行登录');
});
put请求

浏览器无法浏览,需在postman软件浏览

// localhost:3000/editUser
app.put("/editUser",(req,res)=>{
  console.log('修改用户');
  res.send('修改用户');
});
delete请求

浏览器无法浏览,需在postman软件浏览

// localhost:3000/delete
app.delete("/delete",(req,res)=>{
  console.log('删除用户');
  res.send('删除用户');
});
二级路由
// http://localhost:3000/admin/user
app.get("/admin/user",(req,res)=>{
  res.send('admin user');
});

动态路由

配置路由也要注意顺序,下方的/article/add路由会被上方的/article/:id路由拦截,

//http://localhost:3000/article/xxx   xxx为任意字母
app.get("/article/:id",(req,res)=>{  //这个路由已经包括了下方的/article/add路由
  var id = req.params['id']; 
  res.send('动态路由'+id);   // 动态路由xxx
});
// 要匹配到这个,需要把这个移动到上面的之前
app.get("/article/add",(req,res)=>{ // 匹配到了上面的/article/:id,该/article/add不会匹配
  res.send('article add');   // 动态路由xxx
});

更好两个路由顺序可以访问/article/add路由,代码如下

app.get("/article/add",(req,res)=>{
  res.send('article add');   // article add
});
app.get("/article/:id",(req,res)=>{ 
  var id = req.params['id']; 
  res.send('动态路由'+id);   // 动态路由xxx
});
get 传值
// localhost:3000/product?id=123&cid=123
app.get("/product",(req,res)=>{
  let query = req.query; // 获取传值
  console.log(query);  // {id:'123',cid:'123'}
  res.send('product '+query.id); // product 123
});
const express = require('express')

const app=express()

// get请求,浏览器浏览localhost:3000
// 配置路由
app.get("/",(req,res)=>{
    res.send('你好 express')
});
// get请求,浏览器浏览localhost:3000/article
app.get("/article",(req,res)=>{
    res.send('新闻页面')
});
app.get("/login",(req,res)=>{
  res.send('登入')
});
app.get("/register",(req,res)=>{
  res.send('注册页面')
});
app.post("/doLogin",(req,res)=>{  // post
  console.log('执行登入');
  res.send('执行页面');
});
app.put("/editUser",(req,res)=>{  // put
  console.log('修改用户');
  res.send('修改用户');
});
app.delete("/delete",(req,res)=>{  // delete
  console.log('删除用户');
  res.send('删除用户');
});
// 二级路由
app.get("/admin/user",(req,res)=>{
  res.send('admin user');
});

// 动态路由   配置路由也要注意顺序
app.get("/article/:id",(req,res)=>{  //http://localhost:3000/article/xxx    xxx为任意字母,这个路由已经包括了下方的/article/add路由
  var id = req.params['id']; 
  res.send('动态路由'+id);   // 动态路由xxx
});
// 要匹配到这个,需要把这个移动到上面的之前
app.get("/article/add",(req,res)=>{ // 匹配到了上面的/article/:id,该/article/add不会匹配
  res.send('article add');   // 动态路由xxx
});

// get 传值   http://localhost:3000/product?id=123&cid=123
app.get("/product",(req,res)=>{
  let query = req.query; // 获取传值
  console.log(query);  // {id:'123',cid:'123'}
  res.send('product '+query.id); // product 123
});

app.listen(3000,()=>{
  console.log('已启动');
});

mongoDB数据库

事务:做一个业务操作,有n个步骤,是一个整体:所有的步骤要么全部成功,要么全部失败。

账户表:账号 余额
记录表:账号 操作日期 操作类型

存款操作:
1.在记录表上新增一条存款记录
2.修改账户表对应账号的余额

文件型数据库:
优点:读写数据的效果比较高
缺点:不能很好的处理事件性较强的数据

安装MongoDB,下载community社区版,下载compass(图形化管理工具)
mongodb.com/try/download/community

启动mongodb数据库:
mongodb数据库也是以服务的形式存在于windows操作系统中
法一:win+R进入cmd,输入net start mongodb
法二:打开我的电脑,右击此电脑,选择管理,弹出计算机管理对话框,点击服务和应用程序下的服务,选择MongoDB server,右击后选择菜单中的启动

MongoDB中间件
nodejs平台上提供的访问MongoDB的API

访问数据库步骤:
创建案例代码:
1.创建文件夹,从项目文件中进入cmd,
2.使用express-generator脚手架生成项目代码框架
3.安装中间件:
npm install //安装配置文件中的依赖安装依赖的中间件
npm i mongoose -S // 安装mongoose中间件
4.在项目中新建文件夹—model,
1.连接数据库
let mongoose = require(‘mongoose’);
mongoose.connect(‘连接字符串’,参数);
连接字符串:协议://主机/数据库名mongodb://localhost:27017//dbname
异步方法在es6的语法中:异步方法名(实参).then(成功执行回调函数):异步方法名(实参).catch(失败执行回调函数);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值