nodeJs学习(第一周)

学习总结

nodejs基础知识

核心模块(内置模块)

是一个JS运行时的环境,简单来说就是Node.js可以解析执行JS代码
Node.js中的JS没有BOM、DOM;在Node这个JS执行环境中为JS提供了一些服务器级别的操作API
例如:文件读写、网络服务的构建、网络通信、http服务器等的处理

fs(file-system)文件系统

在Node中如果执行文件操作必须引入fs这个核心模块;在fs这个核心模块中,就提供了所有的文件操作相关的API

var fs = require('fs')
fs.mkdir(path,callback)		创建文件夹
fs.rename()		更改文件名
fs.rmdir(path,callback)		删除文件夹,文件夹只能是空的
fs.stat()		判断是文件还是文件夹
fs.stat('./node01',(err,stats)=>{
  if(stats.isFile()){
    console.log('is file)
  }else{
    console.log('is dir')
  }
})
fs增删查改

fs.readFile用来读取文件的

// 读文件异步
// 成功
// 		date 数据
//		error  null
// 失败
// 		date  undefined没有数据
//		error  错误对象
// 同步错误处理
// 		try   catch
fs.readFile('./date/helloWorld.txt',function(error,date){
    console.log(date.toString())
})
fs.writeFile()	用来创建文件的
// 写文件
// 成功
// 		文件写入成功
// 		error 是 null
// 失败
// 		文件写入失败
//  	error就是错误对象
      
fs.writeFile('./date/你好.md','大家好,我是檀健次老婆',function(error){
    console.log('文件成功写入')
    if(error){
        console.log('写入失败')
      }else{
        console.log('写入成功')
      }
})

在这里插入图片描述
在这里插入图片描述

fs.appendFile()		用来写入文件

fs.appendFile('./date/你好.md','大家好,我是檀健次老婆',function(error){
    console.log('error')
})
fs.unlink()		用来删除文件

fs.unlink('./date/你好.md','大家好,我是檀健次老婆',function(error){
    console.log('error')
})
url
url.parse()  将url字符串转成对象

const url = require('url')
let urlString = 'https:47.95.207.1:3000/fcj/recommend/hot/hehe?us=123&ps=567#nihao'
let urlObj = url.parse(urlString)
console.log(urlObj)
url.format()  将url对象转成字符

let obj = {
    protocol: 'https:',
    slashes: null,
    auth: null,
    host: null,
    port: null,
    hostname: null,
    hash: '#nihao',
    search: '?us=123&ps=567',
    query: 'us=123&ps=567',
    pathname: '47.95.207.1:3000/fcj/recommend/hot/hehe',
    path: '47.95.207.1:3000/fcj/recommend/hot/hehe?us=123&ps=567',
    href: 'https:47.95.207.1:3000/fcj/recommend/hot/hehe?us=123&ps=567#nihao'
  }
  let string = url.format(obj)
  console.log(string)
Query String
querystring.parst()		将字符串变成对象
querystring.stringify()		将对象变成字符串

const qs = require('querystring')
let string = 'name=mq&pass=123&sex=0'
// 两种写法
let obj = qs.parse(string)
let obj = qs.parse(string,'&','=')
console.log(obj)

在这里插入图片描述

const qs = require('querystring')
let obj = { name: 'mq', pass: '123', sex: '0'}
let string = qs.stringify(obj,'^','?')
console.log(string)

在这里插入图片描述

qs.escape()		编码操作
qs.unescape()	解码操作

http

在Node中专门提供了一个核心模块:http
职责就是创建编写服务器

// 1. 加载http
var http = require('http')

// 2.使用http.createServer()方法创建一个Web服务器
//   返回一个Server实例
var server = http.createServer()

// 3.服务器
//     提供服务:对数据的服务
//     发送请求
//     接受请求
//     处理请求
//     发送响应 
//     注册 request请求事件
//     当客户端请求过来,就会自动触发服务器的request请求事件,然后执行第二个参数;回调处理函数
server.on('request',function(){
    console.log('收到客户端的请求了')
})

// 4.绑定端口号,启动服务器
server.listen(3000,function(){
    console.log('服务器启动成功了,可以通过http://127.0.0.1:3000/ 来访问')
})

在这里插入图片描述

request

请求事件处理函数,需要接收两个参数:

  • Request 请求对象
    请求对象可以用来获取客户端的一些请求信息,比如请求路径
  • Response 响应对象
    响应对象可以用来给客户端发送响应消息
    有一个方法write可以用来给客户端发送响应数据;write可以多次使用,但是最后一定要使用end来结束响应,否则客户端会一直等待
server.on('request',function(request,response){
    console.log('收到客户端的请求了,请求路径是' + request.url)

    response.write('hello nodejs')
    response.end()

  // 简单写法
  response.end('hello  nodejs')
})

在这里插入图片描述

根据不同的请求路径发送不同的响应结果
  1. 获取请求路径
    req.url获取到的是端口号之后的那一部分路径;所有的url都是以/开头的
  2. 判断路径处理响应
server.on('request',function(req,res){
    var url = req.url
    console.log(url)
    if(url === '/' ){
        res.end('index page')
    }else if(url === '/Login'){
        res.end('Login page')
    }else{
        res.end('404 Not Found.')
    }
})

在这里插入图片描述

server.on('request', function (req, res) {
    var url = req.url
    if (url === '/products') {
        var products = [
            {
                name: '苹果 15',
                price: 9999
            },
            {
                name: '菠萝 15',
                price: 5000
            },
            {
                name: '小辣椒 15',
                price: 1999
            },
        ]
        // 响应内容只能是二进制数据或字符串
        res.end(JSON.stringify(products))
    }
})

在这里插入图片描述

require

是一个方法
作用
一、是用来加载模块并执行里面的代码的;
在Node中,模块有三种:
具名的核心模块,例如 fs http
用户自己编写的文件模块 相对路径必须加 ./ 可以省略后缀名
在Node中没有全局作用域,只有模块作用域(文件作用域)

  • 外部访问不到内部
  • 内部也访问不到外部
  • 默认都是封闭的
var foo = 'aaa'
console.log('a  start')
require('./b.js')
console.log('a end')
console.log('foo的值是:' + foo)
console.log('b  start')
var foo = 'bbb'
require('./c.js')
console.log('b  end')
console.log('ccc')

在这里插入图片描述
二、拿到被加载文件模块导出的接口对象
每个文件模块中都提供了一个对象:exports
exports 默认是一个空对象

var bExports = require('./b')
var fs = require('fs')
console.log(bExports.foo)
console.log(bExports.add(10,30))

bExports.readFile('./a/js')

fs.readFile('./a.js',function (err,date) {
    if(err){
        console.log('读取文件失败')
    }else{
        console.log(date.toString())
    }
})
var foo = 'bbb'
exports.foo = 'hello'
exports.add = function(x,y){
    return x + y
}

exports.readFile = function(path,callback){
    console.log('文件路径:',path)
}

在这里插入图片描述

ip地址和端口号

IP地址用来定位计算机
端口号用来定位具体的应用程序
所有需要联网通信的应用程序都会占用一个端口号

Content-Type

在服务器默认发送的数据是utf-8编码的内容,但浏览器不知道,中文操作系统默认是gbk
不同的资源对应的Content-Type是不一样,具体参照:http://tool.oschina.net/commons
对于文本类型的数据,最好都加上编码,目的是为了防止中文解析乱码问题
在http协议中,Content-Type就是用来告知对方我给你发送的数据内容是什么类型

var http = require('http')
var server = http.createServer()
server.on('request',function(req,res){
    res.setHeader('Content-Type','text/plain;charset=utf-8')
    res.end('hello  檀健次')
})
server.listen(3000,function(){
    console.log('Server is running...')
})

在这里插入图片描述
如果发送的是html格式的字符串,则也要告诉浏览器我发送的是text/html格式的内容

var http = require('http')
const { default: test } = require('node:test')
var server = http.createServer()
server.on('request',function(req,res){
    // res.setHeader('Content-Type','text/plain;charset=utf-8')
    // res.end('hello  檀健次')

    var url = req.url
    if(url === '/plain'){
        res.setHeader('Content-Type','text/plain;charset=utf-8')
        res.end('hello  檀健次')
    }else if(url === '/html'){
        res.setHeader('Content-Type','text/html;charset=utf-8')
        res.end('<p>hello html<a>点我</a></p>')
    }
})
server.listen(3000,function(){
    console.log('Server is running...')
})

在这里插入图片描述
通过网络发送文件

  • 发送的并不是文件,本质上来讲发送是文件的内容
  • 当浏览器收到服务器响应内容之后,会根据你的Content-Type进行对应的解析处理
var fs = require('fs')
var http = require('http')
const { default: test } = require('node:test')
var server = http.createServer()
server.on('request',function(req,res){
    var url = req.url
    if(url === '/'){
        fs.readFile('./resource/index.html',function(err,data){
            if(err){
                res.setHeader('Content-Type','text/plain;charset=utf-8')
                res.end('文件读取失败,请稍后重试!')
            }else{
                res.setHeader('Content-Type','text/html;charset=utf-8')
                res.end(data)
            }
        })
    }else if(url === '/a'){
        fs.readFile('./resource/aaa.jpg',function(err,data){
            if(err){
                res.setHeader('Content-Type','text/plain;charset=utf-8')
                res.end('文件读取失败,请稍后重试!')
            }else{
                res.setHeader('Content-Type','image/jpeg')
                res.end(data)
            }
        })
    }
    
})
server.listen(3000,function(){
    console.log('Server is running...')
})

在这里插入图片描述
在这里插入图片描述

第三方模块

nodemailer 可以实现发邮件
npm install jquery --save
npm官网 [http://www.npmjs.com/]

const nodemailer = require("nodemailer");

// 创建发送邮件的对象
const transporter = nodemailer.createTransport({
    host: "smtp.ethereal.email", // 发送方邮箱   通过lib/well-known/services.json
    port: 587, // 端口号
    secure: false, // Use `true` for port 465, `false` for all other ports
    auth: {
        user: "maddison53@ethereal.email",  // 发送方的邮箱地址
        pass: testAccount.pass, // mpt 验证码
    },
});

// 邮件信息
let mailobj = {
    from: '"Maddison Foo Koch 👻" <maddison53@ethereal.email>', // sender address
    to: "bar@example.com, baz@example.com", // list of receivers
    subject: "Hello ✔", // Subject line
    text: "Hello world?", // plain text body
    html: "<b>Hello world?</b>", // html body
}

// 发送邮件
transporter.sendMail(mailobj,(err,data)=>{
    console.log(err)
    console.log(data)
})

express

登录接口逻辑分析

1.接收用户传递数据
2.处理数据
3.返回数据

express的基本使用

1.安装

npm  install express -save

第三方模块引用,从当前目录的node——modules以此向上寻找
2.简单使用

const express = require('express')
const app = express()
// express 实例化

// 最简单的api接口
app.get('/user/login',(req,res)=>{
    console.log('你好')
    res.send({err:0,msg:'regist ok'})
})
app.listen(3000,()=>{
    // 监听3000端口  开启服务器
    console.log('server start')
})

在这里插入图片描述

服务器相关

服务器:

1.服务器就是一台电脑
2.服务器软件(apach tomcat iis ngnix node)
3.服务器IP 和端口号
局域网:服务器通过网线(无线)连接,每个电脑都会有一个ip
外网:
ip:确定服务器主机的位置
port:确定服务器里某个应用程序

api接口构成要素

ip
port
pathname 语义化,见文知意
method get post
接收用户传递数据 数据格式由后端确定的

postman 接口测试

api接口书写

接受数据

  • get req.query
  • post req.body 需要body-parser 插件进行解析
  • 注意数据格式 json x-www-form-urencode formdata
const express = require('express')
const app = express()
// express 实例化
const bodypaser = require('body-parser')
// app.use  使用中间插件
// 解析表单数据
// 解析form表单
app.use(bodypaser.urlencoded({extended:false}))
// 解析json 数据
app.use(bodypaser.json())

// 最简单的api接口
app.get('/user/login',(req,res)=>{
    // 接收get参数   req.query
    console.log(req.query)
    console.log('你好')
    let {us,ps} = req.query
    // 处理参数
    if(us === 'mq' && ps == 456){
        res.send({err: 0,msg:'regist ok'})
    }else{
        res.send({err: -1,msg:'us pass no ok'})
    }
    
})

app.post('/user/reg',(req,res)=>{
    // 接收post数据  消息体  请求体   req.body
    let {us,ps} = req.body
    console.log(req.body)
    // express 不能直接解析消息体
    // 通过第三方插件实现解析
    if(us == 123 && ps == 123){
        res.send({err: 0,msg:'regist ok'})
    }else{
        res.send({err: -1,msg:'us pass no ok'})
    }


})

app.listen(3000,()=>{
    // 监听3000端口  开启服务器
    console.log('server start')
})

middlewear 中间件

内置中间件 static
自定义中间件(全局 局部)
第三方中间件 (body-parser)(拦截器)
中间件使用 一定注意next

const express = require('express')
const app = express()
// 拦截器
app.use('/',(req,res,next)=>{
    console.log('中间件')
    let {token} = req.query
    if(token){
        next()   // 是否继续往下执行
    }else{
        res.send('缺少token')
    }
})

app.get('/test1',(req,res)=>{
    console.log('test1')
    // let {token} = req.query
    // if(token){
    //     res.send('ok')
    // }else{
    //     res.send('no ok')
    // }

    res.send('test1')
})

app.get('/test2',(req,res)=>{
    console.log('test2')
    // let {token} = req.query
    // if(token){
    //     res.send('ok')
    // }else{
    //     res.send('no ok')
    // }

    res.send('test2')
})

app.listen(3000,()=>{
    console.log('server  start')
})
const express = require('express')
const app = express()

app.get('/test1',(req,res,next)=>{
    console.log('fun1')
    next()
},s
(req,res)=>{
    console.log('fun2')
    res.send('test1')
})
// app.get('/pathname',fun,fun,...)


app.listen(3000,()=>{
    console.log('server  start')
})

静态资源目录 static

指定一个目录,目录可以被访问

const express = require('express')
const path = require('path')
const app = express()
console.log(__dirname)    // 当前文件所在的绝对路径
console.log(path.join(__dirname,'./data'))     // 拼接路径
app.use(express.static(path.join(__dirname,'./data')))    // 写法一
app.use('/',express.static(path.join(__dirname,'./data')))    // 写法二
app.listen(3000,()=>{
    console.log('server  static')
})

路由

user/add
user/del
food/add
food/del

const express = require('express')
const app = express()
// app.get('/user/add',(req,res)=>{
//     res.send('user/add ok')
// })
// app.get('/user/del',(req,res)=>{
//     res.send('user/del ok')
// })

let userRouter = require('./router/userRouter')
let foodRouter = require('./router/foodRouter')
app.use('/user',userRouter)
app.use('/food',foodRouter)

app.listen(3000,()=>{
    console.log('server  static')
})
const express = require('express')
const router = express.Router()   //获取路由的实例

router.get('/add',(req,res)=>{
    res.send('food add')
})
router.get('/del',(req,res)=>{
    res.send('food del')
})


module.exports = router
const express = require('express')
const router = express.Router()   //获取路由的实例

router.get('/add',(req,res)=>{
    res.send('food add')
})
router.get('del',(req,res)=>{
    res.send('food del')
})


module.exports = router

异步回调 promise

1.封装promise 解决回调地狱

function test(){
  // 返回promise
  return new Promise((resolve,reject)=>{
    // 需要的异步处理
    成功的时候  resolve
    失败的时候  reject
  })
}

2.根据顺序 形成链式调用
test( ).then( ).then( ).catch( )
3.捕获错误

const { rejects } = require('assert')
const { promises } = require('dns')
const fs = require('fs')
const { resolve } = require('path')
function isEixt(){
    return new Promise((resolve,reject)=>{
        fs.stat('./hehe.js',(err,stats)=>{
            if(err){
                reject('文件不存在')
            }else{
                resolve('文件存在')
            }
        })
    })
}

function delFile(){
    return new Promise((resolve,reject)=>{
        fs.unlink('./hehe.js',(err)=>{
            if(err){
                reject('del no ok')
            }else{
                resolve('del ok')
            }
        })
    })
}

isEixt()
.then(()=>{
    console.log('is exit 的成功处理')
    return delFile()
})
.then(()=>{
    console.log('删除文件的成功处理')
})
.catch((err)=>{
    console.log('chatch')
    console.log(err)
})

注:一组链式调用中只需要一个catch;如何手动终止链式调用的执行 抛出一个错误

.then(()=>{
    console.log('删除文件的成功处理')
  throw new Error('手动终止')
})

生活总结

项目结束,没有那么赶,这周倒是不那么忙了,时间不是很紧迫了,nodejs有些偏后端,对于自己来说还是不太好学的,还是得下点功夫,这次的考核,要自己写接口和页面,不是很简单,亚历山大。周末突然加了认知实习,还要手写两千字总结,真的没什么意义啊啊啊啊啊,还浪费时间,我好不容易盼来的周末假期,,真的够了。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值