当前位置: 首页 > article >正文

Node.js学习指南

一、模块化规范

nodejs使用的模块化规范 叫做 common.js 规范:
每一个模块都有独立的作用域 代码在各自模块中执行 不会造成全局污染
每一个模块都是一个独立的文件(module对象)
模块可以被多次加载(module.exports 属性) 但是仅在第一次加载时执行一次
运行结果会被缓存 如果再次加载会从缓存中获得结果
模块的加载顺序和代码的书写顺序有关

// exports对象是module对象的属性,包含导出的信息
导出:module.exports ={}          // module.exports.a = a || exports.a = a;默认指向以module.exports为准
导入:count a = require('');      //只有自定义模块需要写路径('./index'),导入对象永远是module.exports指向的对象

二、HTTP模块

HTTP模块
//导入模块
const http = require("http");
const https = require("https");

//创建服务
let server = http.createServer((req, res) => {
  // request:解析客户端的请求
  //常用属性及方法:url(请求路径) method(请求方法)headers(头部)
  //url:请求的路径,可以根据URL设置出路由模式,express的就是基于此设置的
  //methoe:请求的方式分为,post get delete put patch
  //headers: 请求的头部,客户单的cookie,数据传输的类型等都放在header中
  //data事件:createServer想要获取请求数据体需要监听data事件

  //response:相应客户端请求,常用属性及方法如下:
  //end:res.end()
  //setHeader(name,content),可以设置单个header属性,可以多次设置
  //destory:取消返回
  //statusCode:设置返回的状态码,如200 404 400 500等
  //statusMessage:设置状态码对应返回的信息
  //writeHead:可以同时设置statusCode statusMessage 和多个header属性

  res.writeHead(200, { "content-type": "text/html;charset=utf-8" });
  let data = ""; // 返回数据

  // 根据不同的请求类型 设置不同的响应头
  switch (req.method) {
    case "GET":
      // data事件流 接收到数据时触发的事件 参数 chunk 数据块,在函数内是将数据块拼接给data
      https.get("www.baidu.com", (res) => {
        res.on("data", (chunk) => (data += chunk));
        // end事件 在数据响应结束时触发
        res.on("end", () => {
          data = querystring.parse(data);
          // 接口路由设置 (后端数据接口)
          switch (req.url) {
            case "/users":
              console.log("获取用户信息");
              break;
            case "/addUser":
              // 将数据写入数据库
              data.add = true;
              res.end(JSON.stringify(data));
              break;
            case "/weather":
              weather(res);
          }
        });
      });
      break;
    case "POST":
      const options = {
        hostname: "",
        port: "443",
        path: "",
        method: "POST",
        headers: {
          "content-type": "application/json",
        },
      };
      https.request(options, (res) => {
        res.on("data", (chunk) => (data += chunk));
        // end事件 在数据响应结束时触发
        res.on("end", () => {
          data = querystring.parse(data);
          console.log(daat);
        });
      });
      req.write(JSON.stringify({ name: "", age: "" })); // 发送的请求数据
      req.end();
      break;
    default:
  }
});
//监听3000端口,开启服务
server.listen(3000, () => {
  console.log("打开了3000端口");
});
jsonp跨域
const http = require("http");
const url = require("url");

//创建服务
http
  .createServer((req, res) => {
    res.writeHead(200, { "content-type": "text/html;charset=utf-8" });
    if (req.url === "/favicon.ico") return;
    const urlObj = url.parse(req.url, true);
    res.end(
      `${urlObj.query.callback}(${JSON.stringify({
        name: "xiaoming",
        age: 18,
      })})`
    ); // 返回一个函数 fn( ${urlObj.query.callback} ) 与前端定义的 fn 名称一致
  })
  .listen(3000, () => {
    console.log("打开了3000端口");
  });
cors头跨域
const http = require("http");

//创建服务
http
  .createServer((req, res) => {
    res.writeHead(200, {
      "content-type": "application/json;charset=utf-8",
      "access-control-allow-origin": "*",     // 跨域
    });

    res.end(
      JSON.stringify({
        name: "xiaoming",
        age: 18,
      })
    ); // 返回一个函数 fn( ${urlObj.query.callback} ) 与前端定义的 fn 名称一致
  })
  .listen(3000, () => {
    console.log("打开了3000端口");
  });

三、URL模块

parse模块
const http = require("http");
const url = require("url");

//创建服务
let server = http.createServer((req, res) => {
  res.writeHead(200, { "content-type": "text/html;charset=utf-8" });
  if (req.url === "/favicon.ico") return;
  console.log(url.parse(req.url, true)); // 接收第二个参数,为true则转化query对象
  // =Url {
  //   protocol: null,
  //   slashes: null,
  //   auth: null,
  //   host: null,
  //   port: null,
  //   hostname: null,
  //   hash: null,
  //   search: '?user=b&age=18',
  //   query: [Object: null prototype] { user: 'b', age: '18' },
  //   pathname: '/api',
  //   path: '/api?user=b&age=18',
  //   href: '/api?user=b&age=18'
  // }
  res.end();
});
//监听3000端口,开启服务
server.listen(3000, () => {
  console.log("打开了3000端口");
});
format模块
const url = require("url"); 
const urlObj= {
    protocol: 'https',
    slashes: true,
    auth: null,
    host: 'www.baidu.com:443',
    port: 443,
    hostname: 'www.baidu.com',
    hash: '#tag=110',
    search: '?user=b&age=18',
    query: { user: 'b', age: '18' },
    pathname: '/api',
    path: '/api?user=b&age=18',
  }
url.format(urlObj)   =>  https://www.baidu.com:443/api?user=b&age=18#tag=110
resolve模块
url.resolve('/one/two','three')   => '/one/three'
url.resolve('/one/two/','three')   => '/one/two/three'
url.resolve('http://www.baidu.com/a/b/c','d')   => 'http://www.baidu.com/d'
新url模块
const http = require("http");

let server = http.createServer((req, res) => {
  res.writeHead(200, { "content-type": "text/html;charset=utf-8" });
  if (req.url === "/favicon.ico") return;
  const newUrl = new URL(req.url, "http://localhost:3000");
  console.log(newUrl);

  // URL {
  //   href: 'http://localhost:3000/api?user=b&age=18',
  //   origin: 'http://localhost:3000',
  //   protocol: 'http:',
  //   username: '',
  //   password: '',
  //   host: 'localhost:3000',
  //   hostname: 'localhost',
  //   port: '3000',
  //   pathname: '/api',
  //   search: '?user=b&age=18',
  //   searchParams: URLSearchParams { 'user' => 'b', 'age' => '18' }, // 可迭代对象
  //   hash: ''
  // }

  res.end();
});

server.listen(3000, () => {
  console.log("打开了3000端口");
});

四、querystring模块

const queryatring = require("querystring");

const str = "name=abc&age=18&location=shanghai";
const obj = {
  name: "abc",
  age: "18",
  location: "shanghai",
};

// 将query格式转成对象 
  querystring.parse(str);  
// => [Object: null prototype] {
//   name: 'abc',
//   age: '18',
//   location: 'shanghai'
// }

// 将对象转成query格式字符串  
  querystring.stringify(obj);  
// => "name=abc&age=18&location=shanghai"

五、爬虫模块

cheerio模块
cheerio模块为Node.js 爬虫第三方模块,内置jq基本操作 // npm i cheerio
//加载数据(网页),进行元素操作
let $ = cheerio.load(rawData);

六、path模块

console.log(__dirname); // 当前目录 绝对路径
console.log(__filename); // 当前文件 绝对路径
拼接路径:
path.join(path):
    path.join('__dirname,'a','b');       //拼接当前文件绝对路径
获得文件后缀:
path.extname(path)
获得路径名:
path.dirname(path)

七、event模块

//导入模块
const EventEmitter = require("events");

const event = new EventEmitter();

event.on("start", (data) => {
  console.log("触发了");
  console.log(data);
});

setTimeout(() => {
  event.emit("start", "开始");
}, 2000);

八、fs模块

//导入模块 
count fs = require('fs');
//读取文件
fs.readFile(url,'utf8',(err,data)=>{
    if (err) throw err;
})
//写入文件
fs.writeFile(file,data[,options],callback)
//文件追加
fs.appendFile(file,data[,options],callback)
//修改文件名
fs.rename(oldpath,newpath,callback)
//读取目录
fs.readdir(path[,option],callback(err,files))

九、mysql模块

连接池文件:
const mysql = require('mysql');
var pool = mysql.createPool({ //  创建连接池
    connectionLimit: 10,
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'h5_2013'
});
module.exports = pool;        //导出模块

文件2:
const mysql = require('pool');   //引入导出的配置
执行sql语句:
 mysql.query('select * from users', (err, data) =>
{ // 查数据
            if (err) console.log(err);
            res.send(data); // 发送查询到的数据
});

十、jwt模块

token 令牌
它是一个三段式的加密字符串
xxxxxxxxxx.yyyyyyyyyyyyyyyy.zzzzzzz
第一段: 头信息 签证:安全信息验证 口令 使用不可逆的哈希算法进行加密
第二段: 你需要存储的信息  采用base64 可逆加密 截取一部分
第三段: 额外信息 使用不可逆哈希算法进行加密
浏览器在发送请求进行登陆时 
服务器验证完信息 信息正确 则生产一个 token
服务器将这个token发送给前端 前端进行存储
如果前端请求了需要验证登录权限的页面或数据 前端将token跟随请求发回后端
后端通过解密 验证token的有效性

const jwt = require('jsonwebtoken');

// 生成 token:
// jwt.sign(存储的数据,口令,参数);
// 口令 是一个验证需要的 额外字符串
// 解码token的时候 如果口令不同就无法正确解码

// 解码token:
// jwt.verify(token,口令,回调);

let userInfo = {
    username: 'zhangsan',
    age: 25,
    sex: 'nan',
    phone: 13688888888
};

// 生成token
let token = jwt.sign(userInfo, 'rootbk', { expiresIn: 60 });        //expiresIn 过期时间

// console.log(token);

// 解码token
jwt.verify(token, 'rootbk', (err, data) => {
    if (err) console.log(err.message);
    console.log(data);
})

十一、项目脚手架express

安装
#你可以通过 npx (包含在 Node.js 8.2.0 及更高版本中)命令来运行 Express 应用程序生成器。
$ npx express-generator
#对于较老的 Node 版本,请通过 npm 将 Express 应用程序生成器安装到全局环境中并执行即可。
$ npm install -g express-generator
$ express name 
#然后安装所有依赖包:
$ cd myapp
$ npm install
#然后在浏览器中打开 http://localhost:3000/ 网址就可以看到这个应用了,通过生成器创建的应用一般都有如下目录结构:

- 项目名
    - [bin]       # 存放可执行程序
        - www     # 开启http服务
    - [public]    # 存放静态前端文件
        - [images]
        - [javascripts]
        - [stylesheet]
    - [routes]    # 存放路由文件
        - index.js
        - users.js
    - [views]     # 前端视图模板
        - error.ejs
        - index.ejs
    - app.js      # 主程序
    - package.json   # 依赖信息
处理数据
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
搭建静态web服务
const express = require('express'); // 引入第三方模块的方式和引入内置模块的方式相同
const path = require('path');
const app = express(); // 创建一个express应用
const conf = {
    port: 8888,
    host: '10.31.168.73'
};
// 使用express搭建一个静态的web服务器

// 静态服务器 使用一个中间件实现
// 将public目录 设置成静态的web目录
// public中所有内容都可以在web服务中被访问

// app.use()  使用中间件
app.use(express.static(path.join(__dirname, 'public'))); // 静态服务

app.listen(conf.port, conf.host, () => { // 监听端口启动服务
    console.log(`server is running at http://${conf.host}:${conf.port}`);
});
api服务
// 搭建一个api 服务    应用程序接口
// express可以快速搭建api服务
// 接口的作用是给前端提供数据支持(CRUD)  
// 前端如何发送请求
// ajax    get/post
// href    get
// form    get/post
// jsonp   get

const express = require('express');
const app = express(); // 创建一个express应用
const conf = {
    port: 8088,
    host: 'localhost'
};

// app.get(url,callback);   用于接受get请求
// 参数
// url[string] 请求路径
// callback[function] 回调函数
//    回调参数
//    req      request
//    res      response
//    next     函数 交出中间的控制权 将这个请求交给下一个中间件

app.get('/getItem', (req, res, next) => {
    console.log('我收到了一个请求');
    // 响应内容
    // res.send() 发送数据 接受一个字符串作为参数 发送数据后自动终止请求
    // res.send('hahaha');
    // res.send({ username: 'zhangsan', age: 20 });

    // res.json() 发送数据 接受一个JSON 发送后自动终止请求
    res.json({ data:{username: 'zhangsan', age: 20},status:success });
});
app.get('/getuser', (req, res, next) => {
    res.json({ username: 'lisi', age: 20, success: 1 });
});
app.post('/getuser', (req, res, next) => {
    res.json({ username: 'xiaoming', age: 20, success: 1 });
});
app.listen(conf.port, conf.host, () => {
    console.log(`server is running at http://${conf.host}:${conf.port}`);
});
use中间件
const express = require('express');
const path = require('path');
const app = express();
const conf = {
    port: 8888,
    host: 'localhost'
};
// 配置静态web服务器
app.use(express.static(path.join(__dirname, 'public')));

// express 封装的是 http 服务器
// express 接受到前端发送过来的请求 会交给 中间件 依次处理

// 当前回调函数就是我的自定义中间件
app.use((req, res, next) => {
    console.log('我是中间件一号');

    // 如果在中间中没有使用 send 或 json 结束请求
    // 这个请求会被认为没有完成 进程将被挂起
    // next 调用next可以将中间件的控制权交出 
    // 将这个请求传递给下一个中间件
    next();
    // res.send('hahah');
});
app.use((req, res, next) => {
    console.log('我是中间件二号');
    next();
});
app.listen(conf.port, conf.host, () => {
    console.log(`server is running at http://${conf.host}:${conf.port}`);
});
request模块-实现跨源请求(代理)
const express = require('express');
const request = require('request');
const querystring = require('querystring');
const app = express();
let requestUrl = 'http://api.k780.com/?';
let props = {
    app: 'weather.future',
    cityNm: '杭州',
    appkey: '38926',
    sign: 'f8b4121c2d581be2623569b24f798dee',
    format: 'json'
}
requestUrl += querystring.stringify(props);
app.get('/api', (req, res, next) => {
    request(requestUrl, (err, response, body) => {
        if (err) console.log(err);
        res.send(body);
    });
});
app.listen(8877, 'localhost', () => {
    console.log('start');
});


http://www.kler.cn/a/534285.html

相关文章:

  • InnoDB和MyISAM的比较、水平切分和垂直切分、主从复制中涉及的三个线程、主从同步的延迟产生和解决
  • 论deepseek软件底层原理
  • 什么是数据库代理
  • LabVIEW的智能电源远程监控系统开发
  • SQL Server中RANK()函数:处理并列排名与自然跳号
  • 蓝桥杯刷题DAY3:Horner 法则 前缀和+差分数组 贪心
  • 18爬虫:关于playwright相关内容的学习
  • ES6 对象扩展:对象简写,对象属性 表达式,扩展运算符 ...,Object.assign,Object.is,用法和应用场景
  • 教育邮箱免费使用Notion专业版,还能免费使用Azure和OpenAI!
  • [Leetcode]求最长公共前缀
  • Linux 安装 RabbitMQ
  • 高级java每日一道面试题-2025年01月28日-框架篇[SpringBoot篇]-如何使用Spring Boot实现异常处理?
  • 按月拆分工作表,报表清晰没烦恼-Excel易用宝
  • ubuntu22.40安装及配置静态ip解决重启后配置失效
  • Linux环境部署DeepSeek大模型
  • 深入解析:如何获取商品 SKU 详细信息
  • 双亲委派(jvm)
  • Anaconda中指定python版本安装langchain
  • Django框架丨从零开始的Django入门学习
  • Excel中Address函数的用法
  • Docker深度解析:运行原理
  • C++SLT(三)——list
  • python-leetcode-验证二叉搜索树
  • 基于微信小程序的消防隐患在线举报系统设计与实现(LW+源码+讲解)
  • “message“: “类型注释只能在 TypeScript 文件中使用
  • 网络安全—DDoS攻防