node的语法基础
JavaScript语法
变量
注释
数据类型
函数
闭包
控制台console
console.log()
在REPL环境中输入console
>console
console.log()标准输出流的输出,console.log('node.js is powerful')
console.warn(),console.error(),console.info()
console.warn('%s%s','node.js','is','powerful'); //node.jsis powerful console.warn('%s%s%s','node.js','is','powerful'); //node.jsispowerful console.info('%d','node.js') //NaN console.log('%d','node.js','is','powerful'); //NaN is powerful console.error('%d','node.js'); //NaN console.error('%d','node.js','is','powerful'); //NaN is powerful
console.dir()
用于将一个对象的信息输出到控制台。
const obj={
name:'node.js', get:function(){
console.log('get'); } set:function(){
console.log('set'); } } console.log(obj);
console.time(),console.timeEnd()
用于统计一段代码的运行的时间。
console.time('total time'); console.time('time1'); for(var i=0;i<10000;i++){
} console.timeEnd('time1'); console.time('time2'); for(var i=0;i<10000;i++){
} console.timeEnd('time2'); console.timeEnd('total time');
console.trace()
用于输出当前位置的栈的信息。
node中的包管理
NPM介绍
NPM常用命令
npm -v,npm version;
npm init可以生成package.json文件;
npm install;
package.json文件
package.json文件是一个提供包描述的文件。
模块加载原理与加载方式
require加载模块
对于原生模块:
const http=require('http'); http.createServer( //your code )
对于文件模块:
const myModule=require('./node/myModule')
exports导出模块
node核心模块
http模块——创建HTTP服务器,客户端
node.js服务器端:
const http=require('http'); const server=http.createServer(function(req,res){
//基于事件的http服务器 res.writeHead(200,{
'content-type':'text/plain', }); res.end('Hello node.js'); }); server.listen(3000,function{
console.log('listening port 3000'); });
const http=require('http'); const server=new http.Server(); server.on('request',function(req,res){
//基于事件的http服务器 res.writeHead(200,{
'content-type':'text/plain', }); res.end('Hello node.js'); }); server.listen(3000,function{
console.log('listening port 3000'); });
客户端向http服务器发送请求:
http.request(option[,callback]);
http.get(option[,callback]);
const http=require('http'); let reqData=''; http.request({
'host':'127.0.0.1', 'port':'3000', 'method':'get' },function(res){
res.on('data',function(chunk){
reqData+=chunk; }) res.on('end',function(){
console.log(reqData); }); });
const http=require('http'); let reqData=''; let option={
'host':'127.0.0.1', 'port':'3000' }; const req=http.request(option); req.on('response',function(res){
res.on('data',function(chunk){
reqData+=chunk; }); res.on('end',function(){
console.log(reqData); }); });
url模块——url地址处理
使用url模块
const url=require('url'); let parseUrl='https://www.google.com/?q=node.js'; let urlObj=url.parse(parseUrl); console.log(urlObj)
使用url.format()
const url=require('url'); let urlObj={
'host':'www.google.com', 'port':'3000', 'protocol':'https', 'search':'?q=node.js' }; let urladdress=url.format(urlObj); console.log(urladdress);
querystring模块——查询字符串处理
querystring.parse():将查询字符串反序列化为一个对象,类似JSON.parse();
querystring.stringify():将一个对象序列化为一个字符串,类似JSON.stringify();
const querystring=require('querystring'); let obj={ keyWord:'node.js', name:'huruji' }; let str=querystring.stringify(obj); console.log(str);
node常用模块
util模块——实用工具
util.inspect():返回一个对象反序列化形成的字符串;
util.format():返回一个使用占位符格式化的字符串;
util.log():控制台输出,类似console.log();
const util=require('util'); let obj={
keyWord:'node.js', name:'huruji' }; let str=util.inspect(obj); console.log(str);
path模块——路径处理
path模块提供一系列处理文件路径的工具:
path.join():将所有的参数连接起来,返回一个路径;
path.extaname():返回路径的扩展名;
path.parse():将路径解析成一个路径对象;
path.format():接收路径对象为参数,返回一个完整的路径地址。
const path=require('path'); let outputPath=path.join(_dirname,'node','node.js') console.log(outputPath)
const path=require('path'); const str='C:/frontEnd/node/node.js'; let obj=path.parse(str); console.log(obj);
dns模块
dns模块是域名处理和解析:
dns.resolve():将一个域名解析成一个数组;
dns.lookup():返回第一个被发现的IPv4或IPv6地址;
dns.reverse():通过IP解析域名。
const dns=require('dns'); let domain='baidu.com'; dns.resolve(domain,function(err,address){
if(err){
console.log(err); return; } console.log(address); })
文件系统
node文件系统介绍
同步与异步
const fs=require('fs'); //异步操作读取文件 fs.unlink('./temp/hello',(err)=>{
if(err) throw err; console.log('successfully') })
fs模块中的类和文件的基本信息
文件路径
基本文件操作
打开文件
fs.open(path,flags[,mode],callback)
path:文件的路径;
flags:文件打开方式;
mode:设置文件模式;
callback:回调函数,同时带有二个参数。
flag值 | 说明 |
---|---|
r | 打开文件以读取文件并在文件不存在时引发异常。 |
r+ | 打开文件进行读写。如果文件不存在,则引发异常。 |
rs+ | 以同步模式打开文件以进行读写。 |
w | 打开文件进行写入。如果文件不存在,则会创建该文件。 |
wx | 与“ w”相同,但如果存在路径则失败 |
w+ | 打开文件进行读写。如果文件不存在,则会创建该文件。 |
wx+ | 与“ w +”相同,但如果存在路径则失败。 |
a | 打开要追加的文件。如果文件不存在,则会创建该文件。 |
var fs=require('fs'); fs.open('text.txt','r+',function(err,fd){
if(err){
return console.log(err) }; });
关闭文件
fs.close(fd,callback)
读取文件
fs.read(fd,buffer,offset,length,position,callback)
写入文件
fs.appendFile(file,data[,options],callback)
node网络开发
构建TCP服务器
构建TCP客户端
构建HTTP服务器
利用UDP协议传输数据与发送信息
node数据库开发
express-监听GET和POST请求
req.query
const express = require('express'); const app = express(); app.get('/get', function(req, res) {
// 直接返回对象 console.log(req.query); res.send(req.query) }); app.listen('7777', () => {
console.log('7777'); });
req.params
const express = require('express'); const app = express(); app.get('/get/:id', function(req, res) {
// 直接返回对象 console.log(req.params); // res.json()返回json数据(自动处理)并结束响应 res.send(req.params) // res.send({ name: 'abc' }); }); app.listen('7777', () => {
console.log('7777'); });
托管静态资源
托管多个静态资源目录,多次调用express.static()
const express=require('express') const app=express() app.use(express.static('./public')) app.listen(7777,()=>{
console.log('7777') })
挂载路径前缀
app.use('/public',express.static('./public'))
express路由
在express中,路由指的是客户端的请求与服务器处理函数之间的映射关系。
请求类型,请求的url地址,处理函数;
const express=require('express') const app=express() app.get('/user',(req,res)=>{
res.send('hello world') }) app.post('/user',(req,res)=>{
res.send('post') }) app.listen(7777,()=>{
console.log('7777') })
模块化路由
1.创建路由模块对应的js文件;
2.调用express.Router()函数创建路由对象;
3.向路由实例对象上挂载具体的路由;
4.使用module.exports向外共享路由对象;
5.使用app.use()函数注册路由模块;
const express=express() const router=express.Router() router.get('/user/list',(req,res)=>{
res.send('get user list') }) router.post('/user/add',(req,res)=>{
res.send('add new user') }) module.exports=router
const express=require('express') const app=express() app.listen(7777,()=>{
console.log('http://127.0.0.1') })
为路由模块添加前缀
类似托管静态资源
const express=require('express') const app=express() //导入路由模块 const router=require('./router') //注册路由模块 app.use('api',router) app.listen(7778,()=>{
console.log('http://127.0.0.1') })
中间件
本质上是一个function处理函数;
多个中间件之间,共享同一份req和res。
app.get('/',(req,res,next){
next() })
next()是实现多个中间件连续调用,表示把流转关系转交给下一个中间件或者路由;
定义在中间件函数
const express=require('express') const app=express() const mm=function(req,res,next){
console.log('这是一个最简单的中间件函数') //把流转关系,转交给下一个中间件或者路由 next() } app.listen(7777,()=>{
console.log('7777') })
全局生效的中间件
const express=require('express') const app=express() const mm=function(req,res,next){
console.log('这是一个最简单的中间件函数') //把流转关系,转交给下一个中间件或者路由 next() } app.use(mm) app.listen(7777,()=>{
console.log('7777') })
定义全局生效中间件的简化形式
const express=require('express') const app=express() app.use((req,res,next)=>{
console.log('这是最简单的中间函数') next() }) app.get('/user',(req,res)=>{
res.send('Home page') }) app.listen(7778,()=>{
console.log('7778') })
局部生效的中间件
不使用app.use()定义的中间件,叫做局部生效的中间件。
const mv1=function(req,res,next){
console.log('这是中间件函数') next() } app.get('/',mv1,function(req,res)=>{
res.send('Home Page') })
定义多个中间件
app.get('/',mv1,mv2,(req,res)=>{
res.send('Home Page')}) app.get('/',[mv1,mv2],(req,res)=>{
res.send('layout page')})
中间件的分类
应用级别的中间件
app.use() app.get() app.post()
路由级别的中间件
绑定express.Router()
错误级别的中间件
专门来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题。
错误级别的中间件,必须注册在所有的路由之后;
const express=require('express') const app=express() app.get('/',(req,res)=>{
throw new Error('服务器内部发生错误') res.send('Home Page') }) app.use((err,req,res,next)=>{
console.log(err.message) res.send('Error'+err.message) }) app.listen(7778,()=>{
console.log('7778') })
express内置的中间件
express.static() 托管静态资源 express.json() 解析json格式的请求体数据 express.urlencoded() app.use(express.json())
//raw-json数据 const express=require('express') const app=express() //除了错误级别的中间件,其他的中间件,必须在路由之前进行配置 app.use(express.json()) app.post('/user',(req,res)=>{
//在服务器,可以使用req.body这个属性,来接收客户端发送过来的请求体数据 //默认情况下,如果不配置解析表单数据的中间件,则req.body默认=undefined console.log(req.body) res.send('ok') }) app.listen(7778,()=>{
console.log('7778') })
第三方中间件
自定义中间件
app.use((req,res,next)=>{
})
监听req的data事件
app.use((req,res,next)=>{
let str='' req.on('data',(chunk)=>{
str+=chunk }) })
监听req的end事件
app.use((req,res,next)=>{
let str='' req.on('data',(chunk)=>{
str+=chunk }) req.on('end',()=>{
//str中存放的是完整的请求体数据 console.log(str) }) }) app.use('/user',(req,res)=>{
res.send('ok') })
querystring模块解析请求体数据
解析出来的数据对象挂载为req.body
req.on('end',()=>{
const body=qs.parse(str) req.body=body next() })
将自定义中间件封装为模块
const qs=require('querystring') const bodyParser=(req,res,next)=>{
let str='' req.on('data',(chunk)=>{
str+=chunk }) req.on('end',()=>{
const body=qs.parse(str) req.body=body next() }) } module.exports=bodyParser
const express=require('express') const app=express() //导入封装的中间件模块 const custom=require('./body-parser') app.use(custom) app.post('/user',(req,res)=>{
const body=qs.parse(str) res.send('ok') }) app.listen(7778,()=>{
console.log('7778') })
使用express写接口
编写get接口
const express=require('express') const router=express.Router() router.get('/get',(req,res)=>{
//req.query获取客户端通过查询字符串,发送到服务器的数据 const query=req.query //res.send()方法,向客户端响应处理的结果 res.send({
status:0, msg:'GET请求成功', data:query }) }) module.exports=router
const express=require('express') const app=express() const router=require('./router') app.use('/api',router) app.listen(7777,()=>{
console.log('express server running at http://127.0.0.1') })
编写post接口
const express=require('express') const router=express.Router() router.get('/get',(req,res)=>{
//req.query获取客户端通过查询字符串,发送到服务器的数据 const query=req.query //res.send()方法,向客户端响应处理的结果 res.send({
status:0, msg:'GET请求成功', data:query }) }) router.post('/post',(req,res)=>{
//通过req.body获取请求体中包含的url-encoded格式的数据 const body=req.body res.send({
status:0, msg:'POST请求成功', data:body }) }) module.exports=router
const express=require('express') const app=express() //配置解析表单数据的中间件 app.use(express.urlencoded({
extended:false})) const router=require('./router') app.use('/api',router) app.listen(7777,()=>{
console.log('express server running at http://127.0.0.1') })
CORS跨域资源共享
解决接口跨域问题的方案主要有二种:
CORS(主流的解决方案)
JSONP(有缺陷的解决方案:只支持GET请求)
jsonp接口
浏览器通过
//优先创建jsonp接口 app.get('/api/jsonp',(req,res)=>{
}) app.use(cors)
const express=require('express') const app=express() //配置解析表单数据的中间件 app.use(express.urlencoded({
extended:false})) app.get('/api/jsonp',(req,res)=>{
//定义接口的具体实现过程 const funName=req.query.callback //要发送到客户端的数据对象 const data={
name:'zs',age:22} //拼接出一个函数的调用 const scriptStr=`${
funName}(${
JSON.stringify(data)})` res.send(scriptStr) }) const cors=require('cors') app.use(cors) const router=require('./router') app.use('/api',router) app.listen(7777,()=>{
console.log('express server running at http://127.0.0.1') })
前后端身份认证
服务端渲染使用session认证
前后端分离使用JWT认证
Session认证机制
cookie
存储在用户浏览器中不超过4KB的字符串。由一个名称,一个值和其他;
特征:
1.自动发送;
2.域名独立;
3.过期时限;
4.4KB限制;
配置使用session中间件
npm install express-session const session=require('express-session') app.use( session({
secret:'keyboard cat', resave:false, saveUninitialized:true }) )
向session中存数据
app.post('/',(req,res)=>{
if(req.body.username!=='admin'||req.body.password!=='000000'){
return res.send({
status:1,msg:'登陆失败'}) } //成功配置express-session这个中间件之后,才能通过req点出来这个session属性 req.session.user=req.body //用户的信息 req.session.islogin=true //用户的登陆状态 })
从session中取数据
app.get('/',(req.res)=>{
//判断用户是否登录 if(!req.session.islogin){
return res.send({
status:1,msg:'fail'}) } res.send({
status:0, mgs:'success', username:req.session.user.username }) })
清空session
app.post('/',(req,res)=>{
req.session.destroy() res.send({
status:0, msg:'退出登录成功' }) })
JWT认证机制
JWT的组成部分
header,payload(有效载荷),signature(签名)
Header.Payload.Signature
导入jwt相关的包
//导入用于生成jwt字符串的包 const jwt=require('jsonwebtoken') //用于将客户端发送过来的jwt字符串,解析还原成json对象的包 const expressJWT=require('express-jwt')
定义secret密钥
为了保证jwt字符串的安全性,防止jwt字符串在网络传输过程中被别人激活成功教程,需要定义一个用于加密和解密的secret密钥:
const secretKey='ithema No1'
登录成功后生成jwt字符串
调用jsonwebtoken包提供的sign()方法,将用户信息加密成jwt字符串,响应给服务器:
app.post('/api/login',(req,res)=>{
res.send({
status:200, messsage:'登录成功', //调用jwt.sign()生成jwt字符串,三个参数分别是:用户信息对象,加密密钥,配置对象 token:jwt.sign({
username:userinfo.username},secretKey,{
expiresIn:'30s'}) }) })
将jwt字符串还原为json对象
客户端每次在访问哪些有权限接口时,都需要主动通过请求头中的Authorization字段,将token字符串发送到服务器进行身份认证。
服务器通过express.jwt中间件,自动将客户端发送过来的token解析成json对象;
app.use(expressjwt({
secret:secretKey}).unless({
path:[/^\/api\//]}))
使用req.user获取用户信息
项目
根据id获取文章分类数据
exports.get_cate={
params:{
id } } router.get('/cates/:id',expressJoi(get_cate),artcate_handler.getArtcateById) exports.getArtcateById=(req,res)=>{
const sql=`select * from ev_article where id=?` db.query(sql,req.params.id,(err,results)=>{
if(err) return res.cc(err) if(results.length!==1) return res.cc('获取文章分类数据失败!') res.send({
status:0, message:'获取文章分类数据成功!', data:results[0] }) }) res.send('ok') }
postman
前端
export const deleteRoom=(roomid)=>{
return http({
url:`/location/delete/${
roomid}`, method:'GET', }) } const handleDelete =async (row) => {
const res=await deleteRoom(row.roomid) if(res.data.status===0){
ElMessage({
type: 'success', message:res.data.message }) getAll() }else{
ElMessage.error(res.data.message) } console.log(res.data) };
根据id获取数据
const db=require('../db/index') exports.getArtcate=(req,res)=>{
//未删除为0,删除为1 const sql=`select * from ev_article_cate where is_delete=0 order by id asc` db.query(sql,(err,results)=>{
if(err) return res.cc(err) res.send({
status:0, message:'获取文章分类数据成功', data:results }) }) res.send('ok') }
前端
export const getAllAPI=()=>{
return http({
url:'/location/all', method:'GET' }) }
根据id新增数据
exports.postArtcate=(req,res)=>{
//定义查询的name与alias是否被占用的sql语句 const sql=`select * from ev_article_cate where name=? or alias=?` db.query(sql,[req.body.name,req.body.alias],(err,results)=>{
if(err) return res.cc(err) if(results.length===2) return res.cc('name,alias被占用') if(results.length===1 && results[0].name===req.body.name&&results[0].alias===req.body.alias) return res.cc('name,alias被占用') if(results.length===1&&results[0].name===req.body.name) return res.cc('name,alias被占用') if(results.length===1&&results[0].alias===req.body.alias) return res.cc('name,alias被占用') //TODO 都可用,执行添加 const sql=`insert into ev_artcile_cate set ?` db.query(sql,req.body,(err,results)=>{
if(err) return res.cc(err) if(results.affectedRows!==1) return res.cc('新增文章分类失败!') res.cc('新增文章分类成功!',0) }) }) }
postman
前端
export const addUser = (formData) => {
const data = new URLSearchParams(formData); return http({
url: '/location/adduser', method: 'POST', headers: {
'Content-Type': 'application/x-www-form-urlencoded', }, data: data.toString() }); } const form = ref({
locationid: '', roomid:'', sum:'', is_delete:0 }) const adddialog=async()=>{
dialogFormVisible.value=false const res=await addUser(form.value) console.log(res.data) if(res.data.status===0){
ElMessage({
type: 'success', message: '新增宿舍成功' }) getAll() }else{
ElMessage.error('新增宿舍失败') } }
根据id更新数据
//校验规则 exports.update_cate={
body:{
id, name, alias } } router.post('/updatecates',expressJoi(update_cate),artcate_handler.updateCateById) exports.updateCateById=(req,res)=>{
//定义查重的sql语句 const sql=`select * from ev_article where Id<>? and (name=? or alias=?)` db.query(sql,[req.body.Id,req.body.name,req.body.alias],(err,results)=>{
if(err) return res.cc(err) //判断name,alias if(results.length===2) res.cc('name,alias被占用') if(results.length===1&&results[0].name===req.body.name&&results[0].alias===req.body.alias) res.cc('name,alias被占用') if(results.length===1&&results[0].name===req.body.name) res.cc('name被占用') if(results.length===1&&results[0].alias===req.body.alias) res.cc('alias被占用') const sql=`update ev_article set ? where Id=?` db.query(sql,[req.body,req.body.Id],(err,results)=>{
if(err) return res.cc(err) if(results.affectedRows!==1) return res.cc('更新失败') res.cc('更新文章分类成功',0) }) }) res.send('ok') }
根据id删除数据
//验证规则对象----删除 const id=joi.number().integer().min(1).required() exports.delete_cate={
params:{
id } } router.get('/delete/:id',expressJoi(delete_cate),artcate_handler.deleteCateById) exports.deleteCateById=(req,res)=>{
const sql=`update ev_article set is_delete=1 where id=? ` db.query(sql,req.params.id,(err,results)=>{
if(err) return res.cc(err) if(results.affectedRows!==1) return res.cc('删除文章分类失败!') res.cc('删除文章分类成功!',0) }) res.send('ok') }
到此这篇node做后端的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/hdkf/3812.html