node.js

152 阅读8分钟

认识 node.js

  • node.js是一个开源、跨平台的JavaScript运行时环境

命令行基本操作

  • win: cmd
  • MAC: 终端
  • cmd打开方式1:
  1. win+r
  2. 输入cmd按下回车
  3. 打开的路径默认是系统路径
  • cmd打开方式2

    1. 找到对应文件所在文件夹
    2. 在文件夹路径上单击一下,输入cmd敲回车
  • 命令行常用操作

    1. 返回上一级: 输入命令: cd ..
    2. 查询当前目录内的子目录: 输入命令 :dir
    3. 进入对应目录: 输入命令: cd 文件夹名字
    4. 清屏: 输入命令: cls clear

如何利用 node 执行 js 代码

  • 利用 node 执行 js 代码:
  • 方式1:
  • 打开 cmd, 目录无所谓
  • 输入命令 node 直接敲回车
  • 进入一个线程, 相当于 浏览器控制台, 我们可以在内部书写 JS 代码
  • 缺点:
    1. 没提示
    1. 书写的代码 没有办法保存
  • 方式2:
    1. 将需要运行的 JS 代码 书写在 .js 文件内
  • 打开 cmd, 目录需要在这个 JS 文件的目录
  • 输入命令 node 文件名

node 模块化开发

  • nodejs模块的分类
  1. 自定义模块:自己携带模块
  2. 内置模块: nodejs提供的模块
  3. 第三方模块
  • 导出------node中每一个JS文件都自带一个module
  • 导出语法1: module.exports.属性名 = 属性值
  • 导出语法2: module.exports = 新值
  • 导出语法3: exports.属性名 = 属性值
  • 导入-----node 中 每一个 JS 文件 都自带一个 require
  • 语法: require('地址')
  • Module {
            id: '.',
            // 当前文件所在目录
            path: 'C:\Users\41099\Desktop\GY-2203\07周\02天\code',
            // 记录了, 当前文件 导出的内容
            exports: {},
            // 当前文件完整的 文件名
            filename: 'C:\Users\41099\Desktop\GY-2203\07周\02天\code\04_nodejs的模块化.js',
            // 是否被引入
            loaded: false,
            // 表明当前文件 导入了 什么模块
            children: [],
    

node 内置模块 fs

  • node给我们提供的操作文件/文件夹的能力
  • 导入

  • const fs = require('fs')
    
  • fs.readFile('文件路径','配置项','回调函数')

  • 文件路径:必传

  • 配置项:选填 默认值:buffer,可以手动配置

  • 回调函数:必填

    1. 异步读取文件
  • fs.readFile('./index.txt', 'utf-8', function (err, data) {
        /**
         *  err: 如果读取失败, 会给一个 err
         *  data: 读取成功,文件的内容
        */
        if (err) return console.log(err)
        console.log(data)
    })
    

2.同步读取文件

// 2. 同步读取文件
let data = fs.readFileSync('./index.txt', 'utf-8')
console.log(data)

3.异步写入文件

/**
 *  3. 异步写入
 *      1. 按照指定第一个 参数 去书写 文件的内容(覆盖)
 *      2. 按照指定的第一个参数 没找到, 在指定位置, 新建一个文件出来, 新建的值, 就是第二个参数
*/
fs.writeFile('./index123.txt', '你好', function (data) {
    console.log('写入完成')
})
​

内置模块 path

  • node给我们提供的操作路径相关的内容
  • 导入
  • const path = require("path");
    
  1. path.join([路径片段1,路基片段2,路径片段3])

    // path.join([路径片段1, 路径片段2, 路径片段3])
    const res = path.join("a", "/b", "/c", "/d.html");
    // console.log(res); // a\b\c\d.html
  2. path.resolve

    const res1 = path.resolve("a", "/b", "/c", "/d.html");
    const res2 = path.resolve("q/w/e", "y.html");
    // console.log(res1); // C:\d.html
    // console.log(res2); // C:\Users\41099\Desktop\GY-2203\07周\02天\code\06_node内置模块path\q\w\e\y.html
    
  3. const res3 = path.parse(
        'C:/Users/41099/Desktop/GY-2203/07周/02天/code/06_node内置模块path/q/w/e/y.html'
    )
    console.log(res3)
    ​
    /*
    ​
        {
            // 根路径
            root: 'C:/',
            // 当前文件所在的文件夹(目录)路径
            dir: 'C:/Users/41099/Desktop/GY-2203/07周/02天/code/06_node内置模块path/q/w/e',
            // 完整文件名
            base: 'y.html',
            // 文件后缀
            ext: '.html',
            // 文件名
            name: 'y'
        }
    ​
    */
    

内置模块 url

  • node给我们提供的帮助我们解析url地址信息
  • 导入
  • const url = require("url");
    
  • url.parse('url地址(必填)','是否深度解析(选填,默认为false)')
  • const res = url.parse("http://localhost:8080/a/b/c/d.html?current=1&pagesize=12");
    // console.log(res)
    /*
        Url {
            // 协议
            protocol: 'http:',
            slashes: true,
            auth: null,
            // 域(域名+端口号)
            host: 'localhost:8080',
            // 端口号
            port: '8080',
            // 域名
            hostname: 'localhost',
            // hash值
            hash: null,
            // 携带的参数
            search: '?current=1&pagesize=12',
            // 查询字符串
            query: 'current=1&pagesize=12',
            // 完整路径名
            pathname: '/a/b/c/d.html',
            // 路径(带参数)
            path: '/a/b/c/d.html?current=1&pagesize=12',
            // 完整 url 路径
            href: 'http://localhost:8080/a/b/c/d.html?current=1&pagesize=12'
        }
    */
    ​
    ​
    const res1 = url.parse("http://localhost:8080/a/b/c/d.html?current=1&pagesize=12", true);
    console.log(res1)
    /*
        Url {
            ...
            query: [Object: null prototype] { current: '1', pagesize: '12' },
            ...
        }
    */
    

内置模块 http

  • node给我们提供的开启一个服务器的
  • 导入:
  • const http = require("http");
    
  • // 1. 创建一个 服务器
    const server = http.createServer(function (req, res) {
        /**
         *  req: 表明前端的请求报文
         *  res: 后端返回给前端的响应报文
        */
    ​
        console.log(req.url)
        // console.log('每当有一个 前端 访问的时候, 我就会被触发一次')
    ​
        if (req.url == '/a') {
            res.end('hello~~~pageA')
        }
    ​
        if (req.url == '/b') {
            res.end('hello~~~pageB')
        }
    ​
    })
    ​
    // 2. 给服务器 配置一个 端口号(0~65535)
    server.listen(8080, () => {
        console.log('服务器开启成功, 端口号 8080')
    })
    

补充---请求

  1. JS内部ajax就算一个请求----由ajax发送请求,返回的数据给到了ajax

  2. 在浏览器地址栏内输入地址敲回车----由浏览器发送,返回的数据给到浏览器

  3. img、link、script这些标签也可以发送请求由标签发送,返回的数据给到了标签

    请求地址
     *      http://localhost:8080/a/b/c/index.html
     * 
     *      如果 我请求的 地址是 ./out.js
     *          实际请求的地址
     *              http://localhost:8080/a/b/c/out.js
     * 
     *      如果 我请求的 地址是 ./a/out.js
     *          实际请求的地址
     *              http://localhost:8080/a/b/c/a/out.js
     * 
     *      如果 我请求的 地址是 ../a/out.js
     *          实际请求的地址
     *              http://localhost:8080/a/b/a/out.js
     * 
     * 
     *      如果 我请求的 地址 /a.js
     *          实际请求的地址
     *              http://localhost:8080/a.js
     * 
     * 
     *      如果 我请求的 地址 /a/b.js
     *          实际请求的地址
     *              http://localhost:8080/a/b.js
    */
    

搭建简易服务器

const http = require("http");
const url = require("url");
const fs = require("fs");
​
// 1. 创建一个服务器
const server = http.createServer(function (req, res) {
    const { pathname, query } = url.parse(req.url, true);
    console.log(pathname, query);
​
    if (pathname === "/a") {
        // 1. 读取 ./client/views/index.html 文件, 后续通过 res.end()  返回给浏览器
        fs.readFile("./client/views/index.html", "utf-8", function (err, data) {
            if (err) return console.log(err);
​
            // console.log(data)
            res.end(data);
        });
    }
​
    if (pathname === "/b") {
        fs.readFile("./client/views/list.html", "utf-8", function (err, data) {
            if (err) return console.log(err);
​
            // console.log(data)
            res.end(data);
        });
    }
    1
});
​
// 2. 给服务监听一个端口号
server.listen(8080, () => {
    console.log("服务器开启成功");
});
​

初始搭建

const http = require("http");
const url = require("url");
const fs = require("fs");
const path = require("path");
​
const server = http.createServer(function (req, res) {
    const { pathname, query } = url.parse(req.url, true);
    /**
     *  约定:
     *      如果需要访问 html 文件, 将路径开头 写上 /views  后续拼接上 对应的 文件名
     *          假如要访问 index.html
     *              路径: /views/index.html
     *          要访问 list.html
     *              路径: /views/list.html
     */
    if (/^/views/.test(pathname)) {
        // 拿到文件名
        const { base } = path.parse(pathname);
        // 读取对应文件返回给请求者
        fs.readFile(`./client/views/${base}`, "utf-8", function (err, data) {
            if (err) return console.log(err);
            res.end(data);
        });
    }
​
    /**
     *  约定
     *      如果要访问 css 文件 需要使用 /style 开头 后续拼接上 对应的 文件名
     *          假如 要访问 index.css
     *              路径: /style/index.css
     *          list.css        /style/list.css
     *
     */
    if (/^/style/.test(pathname)) {
        // 拿到文件名
        const { base } = path.parse(pathname);
        // 读取对应文件返回给请求者
        fs.readFile(`./client/css/${base}`, "utf-8", function (err, data) {
            if (err) return console.log(err);
            res.end(data);
        });
    }
});
​
server.listen(8080, () => {
    console.log("服务器开启成功");
});
​

接口和静态资源

const http = require("http");
const url = require("url");
const fs = require("fs");
const path = require("path");
​
const server = http.createServer(function (req, res) {
    const { pathname, query } = url.parse(req.url, true);
    /**
     *  新约定1: 如果 请求 html; css; img; video;
     *          以 /static  后续跟着写上对应的 目录与文件名
     *
     *          如果我需要访问 index.html
     *              路径: /static/views/index.html
     *          如果我需要访问 list.html
     *              路径: /static/views/list.html
     *          如果我需要访问 index.css
     *              路径: /static/css/index.css
     *
     *  新约定2:
     *          以 /static 开头 后续写文件名
     *              如果我需要访问 index.html
     *                  路径: /static/index.html
     *              如果我需要访问 index.css
     *                  路径: /static/index.css
     */
​
    if (/^/static/.test(pathname)) {
        /*
            path.parse(pathname);
            {
                root: '/',
                dir: '/static',
                base: 'list.html',
                ext: '.html',
                name: 'list'
            }
        */
        // 拿到文件的后缀名与文件名
        const { base, ext } = path.parse(pathname);
​
        // 根据后缀名拼接上对应的路径
        let baseUrl = "./client";
        if (ext === ".html") {
            baseUrl += "/views";
        } else if (ext === ".css") {
            baseUrl += "/css";
        }
​
        // 根据处理过的路径读取对应文件返回给请求者
        fs.readFile(`${baseUrl}/${base}`, "utf-8", function (err, data) {
            if (err) {
                fs.readFile("./404.html", "utf-8", (err, data) => {
                    if (err) return;
​
                    res.end(data);
                });
                return;
            }
            res.end(data);
        });
    }
});
​
server.listen(8080, () => {
    console.log("服务器开启成功");
});
​

接受请求参数

const http = require("http");
const url = require("url");
const fs = require("fs");
const path = require("path");
​
const server = http.createServer(function (req, res) {
    const { pathname, query } = url.parse(req.url, true);
    if (/^/static/.test(pathname)) {
        // 拿到文件的后缀名与文件名
        const { base, ext } = path.parse(pathname);
​
        // 根据后缀名拼接上对应的路径
        let baseUrl = "./client";
        if (ext === ".html") {
            baseUrl += "/views";
        } else if (ext === ".css") {
            baseUrl += "/css";
        } else if (ext === ".js") {
            baseUrl += "/js";
        }
​
        // 根据处理过的路径读取对应文件返回给请求者
        fs.readFile(`${baseUrl}/${base}`, "utf-8", function (err, data) {
            if (err) {
                if (ext === ".html") {
                    fs.readFile("./404.html", "utf-8", (err, data) => {
                        if (err) return;
​
                        res.end(data);
                    });
                } else {
                    res.end("");
                }
                return;
            }
            res.end(data);
        });
    }
​
    /**
     *  约定, 所有 接口相关的, 全都 以 /api 开头
     */
    if (/^/api/.test(pathname)) {
        if (pathname === "/api/users/info" && req.method === "GET") {
            // 接收到请求, 去数据库 拿到对应的 数据 返回给 请求者
            const info = {
                code: 1,
                message: "请求 /users/info 接口 成功",
                info: {
                    id: 1,
                    name: "QF666",
                    age: 18,
                },
                youparams: query,
            };
​
            // 返回给前端
            res.end(JSON.stringify(info));
        }
​
        if (pathname === "/api/users/login" && req.method === "POST") {
            /**
             *  接收请求体的数据, 有两个事件
             *
             *      req.on('data', () => {})    每当开始解析请求体, 就会执行, 回调函数接受一个参数
             *                                  这个参数的值就是 ajax send发送时携带的参数 (注意: 该函数会多次执行, 次数不确定)
             *
             *      req.on('end', () => {})     这个函数执行的时候, 表明 请求体 全部解析完成
             */
​
            let str = "";
            req.on("data", (paramsStr) => {
                // 因为请求体内容比较多, 在解析的时候, 可能是分段解析,
                str += paramsStr;
            });
​
            req.on("end", () => {
                console.log(str); // username=QF001&password=123456
                const info = {
                    code: 1,
                    message: "请求 /users/login 接口 成功",
                    youparams: str,
                };
​
                res.end(JSON.stringify(info));
            });
        }
    }
});
​
server.listen(8080, () => {
    console.log("服务器开启成功");
});
​