Node.js篇-安装与配置,基本使用,服务器,项目搭建,调试

news2025/1/24 10:53:18

1.安装与配置

官网下载, 并配置环境变量

查看安装成功/版本号: DOS命令 node -v

运行JS文件: node 文件名.js

2.基本使用

(1)CommonJS模块化

Node.js遵循了CommonJS模块化规范( e.g: 自定义模块 )

使用module.exports 导出

// commonjs模块化开发 
function sum(){  //代码  }
function mul(){  //代码  }
// 向外导出一个
// module.exports = sum
// 导出多个
module.exports = {sum, mul}

使用require()导入

// 引用单个  文件后缀名可不写
// const sum = require('./day01-01-基本使用①')
// 引用同一个文件中的多个方法
const { sum, mul } = require('./01-基本使用①')
// 可直接调用
sum()
mul()

(2)环境初始化

npm 是 Node.js 的包管理工具,用来安装各种 Node.js 的扩展

环境初始化: npm init -y 生成package.json配置文件

(3)第三方模块的使用

1>安装

以moment模块为例: npm i moment -g

安装模块会自动生成node_modules重要文件夹

  • -g 全局安装

  • --save/-S记录在节点下 , 在package.json中"dependencies"节点下生成依赖

  • -dev 开发模式 (--save-dev简写-D)

2>使用

直接使用require()导入模块, 使用即可

// 引入 moment 模块
const moment = require('moment')
console.log(moment.now());
console.log(moment().format());

(4)配置

1>配置运行命令

  • 创建bin/www.js文件

  • 修改package.json的"main"节点程序入口文件

  • 在package.json的"scripts"节点下添加节点"dev":"node bin/www.js"

  • 配置完成后, 程序运行命令为 npm run dev

2>配置启动服务器相关

  • nodemon

监听代码变化, 当文件修改时,自动重启服务器, 避免修改代码后频繁的手动关闭和开启服务器 npm i nodemon --save

  • cross-env

运行跨平台设置和使用环境变量的脚本, 这个迷你的包(cross-env)能够提供一个设置环境变量的scripts,能够以unix方式设置环境变量,然后在windows上也能兼容运行 npm i cross-env --save

  • 配置工具

在package.json的"scripts"节点下

"dev": "cross-env NODE_ENV=develop nodemon node bin/www.js",   //开发模式下
"prd": "cross-env NODE_ENV=production nodemon node bin/www.js"   //生产模式下

3.服务器

(1)创建服务器

在bin/www.js文件中创建服务器

  • 安装并引入http模块

  • 创建服务

  • 启动服务器

// 创建服务器
// 1. 引用 http
const http = require('http')
const {  parse} = require('url')

// 2, 创建服务
const server = http.createServer((req, res) => {
  // req: request请求    res: response响应
}) 

// 3. 启动服务器
server.listen(8081, () => {
  console.log('--------小m的服务器启动成功---------------- ')
})

(2)获取get请求的参数

// // 1. 引用 http 
const http = require('http')
const queryString = require('querystring')
const { URLSearchParams, parse} = require('url')

// 2, 创建服务
const server = http.createServer((req,res)=>{
  // req: request请求    res: response响应
  // 从req中获取请求相关内容
  const { method, url} = req   //获取请求方式
  // console.log(method)  // GET
  // console.log(url)  //   /api/getBlogs?id=1&uname=mm 浏览器地址栏中
  // 解析 url  
  if(method === 'GET'){
    // 获取get请求的所有参数  (参数是 ? 后边的部分) split()会将分割后的字符串放在一个数组中, 参数取 ? 后边的
    const paramsStr = url.split('?')[1]   //  id=1&uname=mm
    const query = {}
//=========================================
    // 方式1: 手动解析url  
/*  // 分割各项参数
    const paramsArr = paramsStr.split('&')   //[id=1, uname=mm]
    // 转换为对象格式
    paramsArr.forEach(item => {
      const param = item.split('=') //将每一项以 = 分割  [id,1] [uname,mm]
      query[param[0]] = param[1]  //对象中每一项的键为param[0]  值为param[1]
    }); */
//=========================================
    // 方式2  安装导入并使用queryString模块
/* // docode() 将字符串转化为对象  parse()也可
    query = queryString.decode(paramsStr)
    // encode 将对象转换为字符串  不写'&','=',也默认转换为id=1&uname=mm格式
    // res.end() 服务器给客户端进行响应 
    res.end(queryString.encode(query,'&','='))//id=1&uname=mm
 */
//=========================================
    // 方式3  通过url获取 使用URLSearchParams模块 (推荐)
    // 创建对象
/*  const urlSearchParams = new URLSearchParams(paramsStr)
    console.log(urlSearchParams); //{ 'id' => '1', 'uname' => 'mm' } 带迭代器的对象
    console.log(urlSearchParams.get('id'));   //1   获取id  
    console.log(urlSearchParams.has('id'));  // true  查看该对象中是否有id属性
    // 解析搜索字符串
    const keys = urlSearchParams.keys() //获取所有的key
    for (const key of keys) {
      console.log(key); // id   uname
      query[key] = urlSearchParams.get(key)  // 对象中的属性为获取到所有keys中的每一项key, 值为key对应的值
    } */
//=========================================
    // 方式4  通过url模块获取引入 并使用 parse()  
    // 参数1:要解析的url地址  参数2:  解析出来的是查询字符串还是查询对象,true是对象 false是字符串, 默认是false  参数3: 是否要解析出来host, 默认false
    const result = parse(url, false)  

    console.log(query);  //{ id: '1', uname: 'mm' }
    req.query = query  //将该对象挂在req.query上边
  }
})

(3)获取post请求的参数

const http = require('http')
const {  parse} = require('url')
// 2, 创建服务
const server = http.createServer((req,res)=>{
  // 设置数据响应格式, 通常以JSON格式
  res.setHeader('content-type','application/json;charset=utf-8')
  // req: request请求    res: response响应
  // 从req中获取请求相关内容
  const { method, url} = req   //获取请求方式
  console.log(url)  //   /api/  浏览器地址栏中
  if(method === 'POST'){
    // 获取请求头信息
    const contentType = req.headers['content-type']
    console.log(contentType);  // applicaton/json   JSON格式发送数据
    // 获取post请求的参数, 需要使用数据监听
    const postParams = ''
    req.on('data', chunk=>{  //data数据流, chunk存储每次来的数据
      postParams += chunk.toString()  //将每次来的数据拼接到字符串中
    })
    // 监听是否结束
    req.on('end', ()=>{
      req.body = JSON.parse(postParams)  //字符串转换为对象, 
      res.end(JSON.stringify({ // 服务器给客户端进行响应
        code: 0,
        message: '成功!',
        data: []
      }))  
    })
  }   
})

(4)应用

// 创建服务器
// 1. 引用 http
const http = require('http')
const {  parse} = require('url')

// 2, 创建服务
const server = http.createServer((req, res) => {
  // req: request请求    res: response响应
  // 解决跨域
  res.setHeader('Access-Control-Allow-Origin','*')
  // 设置数据响应格式, 通常以JSON格式
  res.setHeader('content-type', 'application/json;charset=utf-8')
  // 从req中获取请求相关内容
  const { method, url } = req //获取请求方式
  const obj = parse(url, true)  // get请求 解析url
  req.query = obj.query
  const pathName = obj.pathname //获取请求的地址
  console.log(pathName);
  // 对请求进行处理
  if (method === 'GET' && pathName === '/api/getBlogs') {
    // 获取所有博客信息
    const blogs = [{
      id: 1,
      title: 'aaa',
      content: '哈哈哈哈哈哈哈'
    },{
      id: 2,
      title: 'bbb',
      content: '哈哈哈哈哈哈哈'
    }]
    // 获取参数  过滤
    const id = req.query.id
    let arr = blogs
    if(id){
     arr = blogs.filter(blog => blog.id === 1)
    }
    res.end(JSON.stringify({
      status: 200,
      ok: true,
      data: arr
    }))
  } else if (method === 'POST' && pathName === '/api/login') {
    // post请求 解析url
    let postParams = ''
    res.on('data', (chunk) => {
      postParams += chunk.toSring()
    })
    res.on('end', () => {
      // 将post请求的数据放置在req.body上
      req.body = JSON.parse(postParams) 
      // 获取登录信息
      const { sid, password } = req.body
      if(sid === 'admin' && password === '123456'){
        res.end(JSON.stringify({
          code:1,
          message: '登录成功!',
          token: 'dewefsesdfds'
        }))
      }else{
        res.end(JSON.stringify({
          code:1,
          message: '用户或密码错误!',
          token: ''
        }))
      }
    })
  }
})
// 3. 启动服务器
server.listen(8081, () => {
  console.log('--------小m的服务器启动成功---------- ')
})

(5)代码优化

创建src/handler/serverHandler.js文件, 将www.js中请求处理过程分离, 并在www.js文件中引入

//www.js
// 创建服务器
// 1. 引用 http
const http = require('http')
const serverHandler = require('../src/handler/serverHandler')

// 2, 创建服务
const server = http.createServer(serverHandler)

// 3. 启动服务器
server.listen(8081, () => {
  console.log('--------小m的服务器启动成功---------------- ')
  console.log('            ╭────╮     ┇                   ')
  console.log('     ╓════╮ │┃   ┇ ╓═══║ ╓════╖            ')
  console.log(' ✔   ║    ┇ │┃   ┇ ║   ║ ┇┅┅┅═╛     ♡ ♡ ♡ ')
  console.log('     ║    ┇ ╰════╯ ╙═══╛ ╘═════            ')
  console.log('┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄')
})
//serverHandler.js文件
const { parse } = require('url')
const getBlogsRouter = require('../router/getBlogsRouter')
const userRouter = require('../router/userRouter')

// 获取post请求中的数据
const getPostData = (req) => {
  const promise = new Promise((resolve, reject) => {  //resolve成功  reject失败
    let postParams = ''
    req.on('data', chunk=> {
      postParams += chunk
    })
    req.on('end', () => {
      if (postParams !== '') {
        resolve(JSON.parse(postParams)) //有数据
      } else {
        resolve({}) // 没有参数时,返回{}
      }
    })
  })
  return promise
}

const serverHandler = (req, res) => {
  // req: request请求    res: response响应
  // 设置数据响应格式, 通常以JSON格式
  res.setHeader('content-type', 'application/json;charset=utf-8')
  // 从req中获取请求相关内容
  const { url } = req //获取请求方式
  const obj = parse(url, true) // get请求 解析url
  req.query = obj.query

  getPostData(req).then((data) => {
    req.body = data
    getBlogsRouter(req)?.then(data => {
      res.end(JSON.stringify(data))
    })
    // ? 作用 如果undefined,前边没有拿到数据, 则不执行then()
    // 对post请求进行处理
    userRouter(req)?.then(data => {
      res.end(JSON.stringify(data))
    })
  })
}
module.exports = serverHandler

创建src/router, 将处理业务逻辑与获取数据进行分离,存放各类请求处理

创建src/control目录, 存放数据处理相关,

//blogs.js
// 获取所有博客信息
const blogs = [{
    id: 1,
    title: 'aaa',
    content: '哈哈哈哈哈哈哈',
  },{
    id: 2,
    title: 'bbb',
    content: '哈哈哈哈哈哈哈',
  }]

const getBlogList = (params) => {
  // 获取参数  过滤
  const id = params.id
  if (id) {
    const arr = blogs.filter((blog) => blog.id === 1)
    return arr
  }
  return blogs
}
module.exports = getBlogList
//user.js
const users = [{
    username: 'admin',
    password: '123456',
    realname: 'mm',
  }{
    username: 'admin1',
    password: '123456',
    realname: 'mm1',
  }]

const login = (params) => {
  const { username, password } = params
  if (!username || username === '' || !password || password === '') {
    return {
      code: -1,
      message: '用户名或密码为空',
    }
  } else {
    const result = users.filter(
      (user) => user.username === username && user.password === password
    )
    if (result.length == 0) {
      return {
        code: 0,
        message: '用户名或密码错误',
      }
    } else {
      return {
        code: 0,
        data: result,
        message: '',
      }
    }
  }
}

const updateUser = params => {
  const { id, realname } = params;
  if (!id || id === "" || !realname || realname === "") {
      return {
          code: -1,
          message: 'id或realname不能为空'
      }
  } else {
      const index = users.findIndex(user => user.id === (id - 0));
      if (index === -1) {
          return {
              code: 0,
              message: '找不到该用户'
          }
      } else {
          users[index].realname = realname;
          return {
              code: 0,
              status: true,
              message: '修改成功'
          }
      }
  }
}
module.exports = {
  login,
  updateUser
}

在router中进行调用

// getBlogsRouter.js
const {  parse} = require('url')
const { getBlogList } = require('../control/blogs')

const getBlogsRouter = (req)=>{
  const { method, url} = req
  const obj = parse(url, true)  // get请求 解析url
  const pathName = obj.pathname //获取请求的地址
  if (method === 'GET' && pathName === '/api/getBlogs') {
    // control/blogs.js中获取数据
    const result = getBlogList(req.query)
    // 返回Promise对象
    return Promise.resolve(result)
  } 
}
module.exports = getBlogsRouter 
//userRouter.js
const { parse } = require('url')
const { login, updateUser} = require('../control/user')

const userRouter = (req) => {
  const { method, url } = req
  const obj = parse(url, true) // get请求 解析url
  const pathName = obj.pathname //获取请求的地址
  if (method === 'POST' && pathName === '/api/login') {
    const result = login(req.body);
    return Promise.resolve(result);
  }else if(method === 'POST' && pathName === '/api/updateUser'){
    return Promise.resolve(updateUser(req.body))
  }
}

module.exports = userRouter

(6)数据库

新建src/config/dbconfig.js, 存放数据库配置相关信息

// 数据库配置
const MONGODB_URL = 'mongodb://127.0.0.1:27017'
const DB_NAME = 'mydb01_blogs'
module.exports = {
  MONGODB_URL,
  DB_NAME
}

新建src/dbUtils/mongodbUtil.js,存放数据库工具

// 创建客户端
const mongodbClient = require('mongodb').MongoClient
const { MONGODB_URL, DB_NAME } = require('../config/dbconfig')

const getCollection = ()=>{
  return mongodbClient.connect(MONGODB_URL,{}).then(conn=>{
    // 使用数据库
    const db = conn.db(DB_NAME)
    // 使用集合
    const collection = db.collection('blogs')
    //返回连接
    return Promise.resolve(collection)  
  }).catch(err=>[
    Promise.reject({
      message: err
    })
  ])
}

// 查询
const searchBlogs = (params={}) => {
  return getCollection().then(collection => {
    // console.log('获取成功!');

    // 进行查询
    return collection.find(params).toArray().then(data=>{
      return Promise.resolve(data)
    })
  })
}

// 增加
const addBlogs = (params={}) =>{
  if(Object.keys(params).length === 0){
    return Promise.resolve({
      ok: false,
      count: 0,
      message: "添加失败, 没有参数!!"
    })
  }else{
    return getCollection().then(collection=>{
      return  collection.insertOne(params).then(res=>{
          if (res.acknowledged) {
            return Promise.resolve({
              ok: true,
              count: 1,
              message: "添加成功!"
            })
          } else {
            return Promise.resolve({
              ok: false,
              count: 0,
              message: "添加失败!"
            })
          }
        })
    })
  }

}

module.exports = {
  searchBlogs,
  addBlogs
}

修改blogs.js内容

const { searchBlogs,addBlogs} = require('../dbUtils/mongodbUtil.js')

const getBlogList = (params) => {
  return searchBlogs(params)  //因为searchBlogs方法返回的是promise对象, 故得return
}

const insertBlogs = (params)=>{
  return addBlogs(params)
}

module.exports = {
  getBlogList,
  insertBlogs
}

最后在router的相关文件中, 配置相关路由(e.g: 增删改查...)

4.调试

  • 安装: npm i node-inspect -g

  • 在package.json中的"dev"节点中配置 --inspect=9330

"dev": "cross-env NODE_ENV=develop nodemon --inspect=9330 ./bin/www.js"
  • 在调试的地方写debugger进行调试

  • Chrome浏览器地址栏中输入chrome://inspect, 即可在前台调试

项目目录:

为了让我的服务器启动的时候, 可以好看一点, 哈哈哈哈二话不说, 给大家看效果叭

PreviousNotes:

https://blog.csdn.net/qq_54379580/article/details/126781836?spm=1001.2014.3001.5502

代码压缩包放在这里啦

https://download.csdn.net/download/qq_54379580/87381329

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/159105.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Transformers 和 Tokenizers从头训练一个 language model

这是训练一个 ‘小’ 模型的demo (84 M parameters 6 layers, 768 hidden size, 12 attention heads) – 跟DistilBERT有着相同的layers & heads,语言不是英语,而是 Esperanto 。然后可以微调这个模型在下游的序列标注任务。 下载数据集 Esperant…

代码随想录算法训练营第二天|977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

一、参考资料有序数组的平方 题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html视频讲解: https://www.b…

2.1 面向对象

文章目录初始对象成员方法构造方法其他内置方法封装继承继承的基础语法pass复写和使用父类成员类型注解变量的类型注解函数(方法)的类型注解Union类型多态初始对象 样例: # 定义类 class Student:name Nonegender None # 创建对象 stu_1 …

谷粒商城项目之高级篇笔记(一)

目录1 商城业务1.1 商品上架1.1.1 商品Mapping1.1.2 建立product索引1.1.3 上架细节1.1.4 数据一致性1.1.5 代码实现1)先查库存(商品微服务远程调用库存微服务)2)商品上架,保存到es中(商品微服务远程调用搜…

小波分析——5.使用小波对信号去噪以及重构

文章目录假设有一个原始信号我们在前面的内容中已经介绍过,小波是什么,小波是如何对信号进行分解,以及小波对信号成分是如何分析的,今天在这篇文章,也是整个小波分析最后一个章节里,我们来谈谈小波最重要的…

Java获取上传的文件大小并且转换对文件大小进行单位转化

前言 今天产品提出来一个需求,上传文件的时候要记录文件的大小,并且保存到数据库里面。 正好借着这个机会,分享下对文件大小进行单位转化的一个方法。 获取文件大小(原字节)。 一般和前后端进行文件交互,都是通过MultipartFil…

Spring Boot常用注解,thymeleaf,数据提交

前言 Spring Boot主要解决的是在微服务的架构下简化配置(快速有效),前后端分离,快速开发。提供了快速启动,内嵌容器化web项目,开箱即用提供了默认配置,没有繁琐的xml配置和冗余代码。本文见简单…

GAMES101-图形学入门 LEC3: TRANSFORMATION-2D

文章目录上节内容回顾:本节知识概要Why study transformationModeling 模型变换Viewing 视图变换2D transformations 二维变换ScaleUniform 均匀缩放Non-Uniform 非均匀缩放Reflection Matrix 反射矩阵shear 切变rotate 旋转,默认绕(0,0&…

Wetool 一款高效免费的微信社群管理工具,检查单向好友,自动回复、群发

这是一款高效免费的微信社群管理工具,目前功能主要有客服、机器人、单删查询、自动接受好友、以及群管理的一些工具下面放一下软件功能截图需要注意的是开启此工具需要下载旧版本的微信,这个在软件安装启动页面会自动进行下载。单删改查功能这个功能适用…

python基础篇之循环语句(附加选车牌号小系统开发)

大家好,我是csdn的博主:lqj_本人 这是我的个人博客主页:lqj_本人的博客_CSDN博客-微信小程序,前端,vue领域博主lqj_本人擅长微信小程序,前端,vue,等方面的知识https://blog.csdn.net/lbcyllqj?spm1000.2115.3001.5343 哔哩哔哩欢迎关注&…

【CocosCreator入门】CocosCreator项目创建 | 面板介绍

本文进行创建项目流程和编辑器界面的介绍,熟悉组成编辑器的各个面板、菜单和功能按钮。 目录 一、CocosCreator创建项目 二、CocosCreator编辑器界面 2.1层级管理器 2.1.1界面介绍 2.1.2层级管理器操作 2.2资源管理器(Assets) 2.2.1界…

asp.net c#大型综合管理系统源码 OA+HR+CRM综合办公管理系统源码

分享一套大型协同办公(OAHRCRM)系统源码。 本系统是强大构建系统,为OA办公系统HR人力资源管理系统CRM客户关系管理系统集合而成,人员可以单点登入多个系统完成自己的作业,超方便实用。全套源代码提供,不封…

System Extract 步骤

纲要: 把Composition下的SWC分配到System Description 描述的CAN网络的的ECU上。 System Extract目录 1. Create System Extract 2. Map SWC to ECU instance 3. Maping System Signal to Data Element 4. Create System Extract 1. Create System Extract Ri…

SAP 开发测试生产环境的简单介绍

客户端(即Client),是SAP组织架构里最高层的组织单元,所有数据,包括静态数据(科目、客户、供应商、物料、资产等)、业务数据(采购订单、销售订单、生产订单、维修订单等)都会归属到各个Client下。…

Kettle用法之Windows定时任务

1 概述 前文提到了kettle的定时任务计划,但这个任务需要开启kettle,本文将利用windows的任务计划实现kettle的定时任务。 2 实现方法 需要编写bat文件,然后windows的任务计划调用执行。 3 操作步骤 3.1 第1步 启动spoon,新建一个作业&#xf…

【Linux】编译器 - gcc 函数库

目录 一、背景知识 二、gcc如何执行 1、预处理 2、编译 3、汇编 4、链接 三、函数库 1、初识函数库 2、动静态库 2.1、动态库 2.2、静态库 2.3、动静态库的选择 一、背景知识 使用 vim 编辑器完成代码书写之后,我们需要使用 Linux 中的编译器 gcc 来对…

vLive虚拟直播,助力企业打造线上云年会

2023年农历春节临近,各大企业都纷纷开始筹备年会,面临员工分布各地无法同时参与、内容单一缺乏参与感等局限性,越来越多的企业选择做一场云年会替代传统线下年会。近日,蓝海彤翔集团举办2022年终总结表彰暨2023业务发展规划大会&a…

Transcational与Synchronized或Lock搭配使用导致并发问题

在多线程的情况下,我们经常会用到synchronized或者Lock来保证我们的线程安全。 但是当碰到Transcational之后又会碰撞出什么火花呢? 相信我,看完之后,你一定不会亏 首先回顾一下小知识点: 基于Transactional注解的是…

4.R语言【dplyr包】使用方法

b站课程视频链接: https://www.bilibili.com/video/BV19x411X7C6?p1 腾讯课堂(最新,但是要花钱,我花99😢😢元买了,感觉讲的没问题,就是知识点结构有点乱,有点废话)&…

黑马程序员Java教程学习笔记(二)

学习视频:https://www.bilibili.com/video/BV1Cv411372m 如侵权,请私信联系本人删除 文章目录黑马程序员Java学习笔记(二)数组概述数组定义方式一、访问、注意事项数组定义方式二,元素默认值规则数组遍历、元素求和数组…