当前位置: 首页 > 工具软件 > Swig-NodeJS > 使用案例 >

nodejs

锺离晗昱
2023-12-01

nodejs 介绍

nodejs是运行在服务端的JavaScript;一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

nodejs 的模块

  1. 内置模块 : 可以直接引入使用
  2. 第三方模块 : 需要通过 npm 命令下载安装 然后引入使用
  3. 自定义模块 : 通过 module.exports 和 exports 定义导出模块

不管是什么类型的模块,nodejs都是通过 requier(url) 引入加载模块 (nodejs 使用的 CommonJS规范)

自定义模块

  1. module.exports 自定义导出模块; 导出的是一个对象, 一个文件中只能使用一次module.exports导出,多次会覆盖
// app.js
function fun(){}
let obj = {}

//  真正暴露出去的是 exports 对象, 
module.exports = {
    fun,
    obj
}
  1. 通过exports 自定义导出模块, 导出的是一个具体的值 , 一个文件中可以多次使用exports
// index.js
// 暴露的也是 exports对象,  给对象exports对象添加属性并赋值
exports.fun = function(){}

exports.str = 'hello'

引入模块

所有的模块都是通过 require(url) 引入模块

//  引入内置模块:
const http = require('http')  // 引入内置模块, 直接写模块名字

//  引入自定义模块
const app = require('./app.js') // 特别注意路径,同级目录需要添加 前缀  ./ 

//  引入第三方模块  mysql  
//  在使用第三方模块之前,都要初始化项目 npm  init  -y  生成 package.json 文件
// npm install mysql  --save  // 下载安装  安装的文件的路径和入口文件的关系
// const mysql = require('mysql')

nodejs 搭建服务器

通过内置模块http搭建服务器

  1. 搭建服务器流程
const http = requrie('http');
// 链式写法
http.createServer((request, response) => {
    //  request : 客户端向服务器请求传递的数据  简写req
    //  response : 服务器向客户端响应的数据   简写res
    //  设置响应头  text/html  text/plain
     res.writeHead(200, {"Content-type":"text/html;charset=utf-8"})
    //  响应数据
    response.write('hello world') // 响应的数据; 可以多个
    response.end() // 终止响应  end() 可以接受参数的, 参数依然是响应的数据; 只能有一个; 响应结束后 不能再进行任何相关操作
}).listen(3000, () => {
    console.log('服务是否成功开启')
})


//  分开写的方式
const server = http.createServer((req, res) => {
    res.end('hello')
})

server.listen(3000, () => {

})

nodejs 的文件系统fs

引入fs模块

const fs = require('fs')
  1. 读取文件
fs.readFile(url, (err, result) => {
    //  url 文件的地址
    //  err 读取失败的信息   null : 读取成功
    //  result 读取的结果(数据) 默认是一个buffer类型 通过 toString() 转换
})
  1. 写入文件
//  如果文件不存在则创建 , 文件存在则写入并覆盖原文本内容
fs.writeFile(url, content, () => {
    //  url 文件的地址
    //  content 写入的文件内容
    //  callback 回调函数 写入失败的信息
})
  1. 追加内容
//  如果文件不存在则创建 , 文件存在则追加内容
fs.appendFile(url, content, () => {
    //  url 文件的地址
    //  content 追加的文件内容
    //  callback 回调函数 写入失败的信息
})
  1. 删除文件
fs.unlink(url, () => {
    //    url 文件的地址
     //  callback 回调函数 删除失败的信息
})
  1. 文件的重命名
fs.rename(oldUrl, newName,  () => {
    //    oldUrl 原文本的地址  源文件名字
    //  newName 重新命名文件名   新名字
     //  callback 回调函数 命名失败的信息
})

fs的读流和写流以及管道流

  1. 读流
const read = fs.createReadStream('读取的文件地址');

//  监听读取的数据改变
let body = '' // 接受读取的数据
read.on('data', (chunk) => {
    body += chunk;
})

//  监听数据读取结束 
read.on('end', () => {
    console.log('数据读取完成')  
})

//  监听 读取失败的信息
read.on('error', () => {
     console.log('数据读取失败')  
})

  1. 写流
//  fs.WriteStream 类 继承自 <stream.Writable>
const writeStream = fs.createWriteStream('写入的文件地址');
//  创建写入的数据
let result = 'hello world';

//  写入数据 writable.write() 写入数据到流,并在数据被完全处理之后调用 callback。 如果发生错误,则 callback 可能被调用也可能不被调用。 为了可靠地检测错误,可以为 'error' 事件添加监听器。 callback 会在触发 'error' 之前被异步地调用。
//  writable.write(chunk[, encoding][, callback])
writeStream.write(result);

//  写入完成 调用 writable.end() 表明已没有数据要被写入可写流。 可选的 chunk 和 encoding 参数可以在关闭流之前再写入一块数据。 如果传入了 callback 函数,则会做为监听器添加到 'finish' 事件和 'error' 事件。
//  writable.end(chunk[, encoding][, callback])
writeStream.end(); // 

//  监听 finish 事件和 error 事件

  1. 管道流
//  创建一个读流
const read = fs.createReadStream('读取的文件地址');
//  创建写流
const writeStream = fs.createWriteStream('写入的文件地址');
//  通过管道流实现 数据复制
read.pipe(writeStream)

nodejs 的 path 模块(路径)

对路径进行相关操作

  1. 获取文件的扩展名 path.extname()

path.extname() 方法会返回 path 的扩展名,即 path 的最后一部分中从最后一次出现 .(句点)字符直到字符串结束。 如果在 path 的最后一部分中没有 .,或者如果 path 的基本名称(参见 path.basename())除了第一个字符以外没有 .,则返回空字符串

const path = require('path');
let str = 'index.html';
let res = path.extname(str);

  1. 拼接路径 path.join() 多个参数

path.join() 方法会将所有给定的 path 片段连接到一起(使用平台特定的分隔符作为定界符),然后规范化生成的路径

const path = require('path');
let res = path.join('/foo', '/baz', 'a.html')
//  路径参数不符合规则,则报错 TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received an instance of Array
let res = path.join('./foo', {}, "index.css")
  1. 格式化路径 path.normalize()

path.normalize() 方法规范化给定的 path,解析 ‘…’ 和 ‘.’ 片段。

当找到多个连续的路径段分隔字符时(例如 POSIX 上的 /、Windows 上的 \ 或 /),则它们将被替换为单个平台特定的路径段分隔符(POSIX 上的 /、Windows 上的 \)。 尾部的分隔符会保留。

const path = require('path');
let res = path.normalize('www.baidu.com')
let res = path.normalize('https:///www.baidu.com//index.html') // https:\www.baidu.com\index.html
let res = path.normalize('https:///www.baidu.com/../index.html')  // https:\index.html
  1. 全局变量 __dirname __filename
console.log(__dirname) // 文件所在的目录(不包含文件本身)
console.log(__filename) // 文件所在的目录(包含文件本身) (文件详细的路径)

nodejs 的url模块

处理+ 解析url

  1. 把url字符串转换为url对象
const url = require('url');
let path = 'https://baike.baidu.com/小说/brief#4';
//  把url字符串转换为url对象
let res = url.parse(path); 


//  解析 query查询数据转换为对象 , 需要借助第二个参数  url.parse(path, true); 
let path = 'https://baike.baidu.com/?keyword=小说&brief#4';
let res = url.parse(path, true).query;

nodejs 的 querystring 模块

  1. querystring.parse() 要解析的 URL 查询字符串。 针对的是post请求传递的数据

querystring.parse() 方法将 URL 查询字符串 str 解析为键值对的集合。

const querystring = require('querystring');
//  user=张三&pwd=123456   ===>  {user:张三, pwd:123456}
let body = querystring.parse(data)

nodejs 搭建静态资源服务器

//  自定义模块 
function getType(extname) {
    let type = ''
    switch (extname) {
        case '.html':
            type = 'text/html';
            break;
        case '.css':
            type = 'text/css';
            break;
        case '.js':
            type = 'application/javascript';
            break;
        case '.jpg':
            type = 'image/jpeg';
            break;
        default:
            type = 'text/plain'
    }
    return type;
}

module.exports = {
    getType
}
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
// const mime = require('mime');  // 安装第三方插件 mime   使用 mime.getType(extname)
const { getType } = require('./mime');  // 自定义模块 

http.createServer(function (request, response) {
    //  对请求的资源路径进行解析  pathname 就是资源文件名
    let pathname = url.parse(request.url).pathname;
    //  设置默认加载的页面 (index.html)
    pathname = pathname === '/' ? '/index.html' : pathname;
    //  获取文件的扩展名
    let extname = path.extname(pathname);
    //  根据扩展名 获取文件对应的MIME 类型
    let type = getType(extname);
    //  开始读取静态资源文件
    fs.readFile('资源所在的文件路径' + pathname, (err, result) => {
        if(err){
            response.writeHead(404, {'Content-type':'text/html;charset=utf-8'});
            response.end('资源加载失败')
        }else{
            response.writeHead(200, {'Content-type':`${type};charset=utf-8`})
            response.write(result);
            response.end();
        }
    })
}).listen(3000, () => {
    console.log('Server running at http://127.0.0.1:8081/');
});

nodejs 处理get请求和post请求

处理get请求

const http = require('http');
const url = require('url');
 http.createServer(function (request, response) {
    let query = url.parse(request.url, true).query
    console.log(query);
    response.writeHead(200, { 'Content-Type': 'text/plain;charset=utf-8' });
    if (query.user == 'admin' && query.pwd == '123') {
        response.end('Hello World');
    } else {
        response.end('用户名或密码错误');
    }

}).listen(3000, () => {
    console.log('Server running at http://127.0.0.1:8081/');
});

处理post请求

POST 请求的内容全部的都在请求体中,http.ServerRequest 并没有一个属性内容为请求体,原因是等待请求体传输可能是一件耗时的工作。
比如上传文件,而很多时候我们可能并不需要理会请求体的内容,恶意的POST请求会大大消耗服务器的资源,所以 node.js 默认是不会解析请求体的,当你需要的时候,需要手动来做

const http = require('http');
const querystring = require('querystring');
http.createServer(function (request, response) {    
    //  声明一个变量 body  用来接收传递的数据
    let body = '';
    //  监听data事件, - 当有数据可读时触发。
    request.on('data', (chunk) => {
        body += chunk;
    })
    //  监听 end 事件,  没有更多的数据可读时触发。 证明数据传递结束了(数据传输完成)
    request.on('end', () => {
        body = querystring.parse(body);
        console.log(body);
    })
    response.writeHead(200, { 'Content-Type': 'text/plain;charset=utf-8' });
    response.end('ehello')

}).listen(3000, () => {
    console.log('Server running at http://127.0.0.1:8081/');
});

nodejs 和 ajax前后端交互

  1. 使用nodejs 搭建服务器
const http = require('http');
const url = require('url');
http.createServer((req, res) => {
    //  处理跨域问题
    res.setHeader('Access-Control-Allow-Origin', "*");
    //  如果前端传递了请求的数据, 需要处理 request.url 获取查询字段query 
    let query = url.parse(req.url, true).query
    //  根据用户传递的数据进行相应的操作 : 增删改查   操作数据库
    if(){
        // 查询数据
    }else if(){
        // 添加数据
    }
    res.write(data) // data 就是服务器向客户端响应的数据   这个数据是字符串类型(json字符串)
    res.end();
})
  1. ajax 不能跨域请求资源的原因: 同源策略;
    • (著名的安全策略,请求发送了,服务也接受了。但是返回的数据被拦截了)
    • 同源: 同协议 同端口 同域名
    • 解决方案: 1. 使用jsonp发请求 2. 后端给权限 3. 反向代理
$.ajax({
    url:'服务器的地址';
    type:'get',
    data:{}  // 请求传递的数据
    dataType:'json', // 返回的数据类型
    success:function(data){
        // data 请求成功的数据
        //  根据返回的数据 判断操作时成功还是失败  然后进行下一步操作
    }
})
 类似资料: