nodejs基本应用

nodejs

安装并使用nodejs

安装Nodejs

下载

官网: https://Nodejs.org/en/

中文网:http://Nodejs.cn/

在这里插入图片描述

  • 版本说明

    • LTS: 长期稳定版。 实际项目开发建议使用长期稳定版
    • Current: 最新版。最新版包含了一些新功能,如果想学习最新的功能,则可以使用该版本。但是,最新版可能会有一些未知的bug

安装

  1. 双击安装文件开始安装(不同系统选择对应的安装文件)

  2. 傻瓜式安装,一路 ‘next’ 即可

注意: 安装在英文路径下

测试是否安装成功

在桌面上或者任意一个文件夹,按住 shift 键 , 点击鼠标右键,选择 ‘在此处打开命令窗口’

进入黑窗口后输入: node -vnode --version
在这里插入图片描述

能够看到Nodejs版本号即为安装成功。

在node中运行js

方法1: 进入Node.js REPL。

REPL(Read Eval Print Loop:交互式解释器) 表示一个电脑的环境,类似 Window 系统的终端或 Unix/Linux shell,我们可以在终端中输入命令,并接收系统的响应。

Node 自带了交互式解释器,可以执行以下任务:

  • 读取 - 读取用户输入,解析输入了Javascript 数据结构并存储在内存中。

  • 执行 - 执行输入的数据结构

  • 打印 - 输出结果

  • 循环 - 循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出。
    在这里插入图片描述

  • 通过node 进入REPL。

  • 按下ctrl+c 两次可退出

方法2:执行一个JS文件

先准备好一个js文件,例如:e:/index.js

var a = 1;
console.info(a + 2);

接下来 通过 node `js文件的路径 的格式来执行这个js文件。

注意事项:

  • 输入node回车后,要按两次Ctrl+C,才能回到目录中(Ctrl一直按着不放也可以,松开从新按也可以)
  • 执行js文件时,如果当前命令行目录和js文件不在同一个盘符下,要先切换盘符
  • 执行js文件时,如果当前命令行目录和js文件同一个盘符中,则可以使用相对路径找到js文件并执行

体会,此时执行的js代码或文件和浏览器没有任何关系,他们是通过node执行的

Node概述

node是什么

Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.


Node.js® 是一个基于 Chrome V8 引擎 的 JavaScript 运行时

  • Node全名是Node.js,但它不是一个js文件,而是一个软件

  • Nodejs是一个基于Chrome V8引擎的ECMAScript的运行环境,在这个环境中可以执行js代码

  • Nodejs提供了大量的工具(API),能够让我们完成文件读写、Web服务器创建等功能。

在这里插入图片描述

node让javascript程序员能够一统前后端。

理解node和浏览器的区别

  • 安装了浏览器这个软件,它不但可以执行ECMAScript,浏览器这个软件内置了window对象,所以浏览器有处理DOM和BOM的能力。
  • 安装了NodeJs这个软件,它不但可以执行ECMAScript,NodeJS这个软件也内置了一些东西,包括全局成员和模块系统,同时还可以载入第三方模块来完成更强大的功能。

在这里插入图片描述

node的主要内容

在这里插入图片描述

node中的全局变量

node中有一个全局变量global,是node中最大的一个对象,相当于浏览器中的window对象。global中的成员在使用时,可以省略global,这点也类似浏览器中的window

下面介绍几个全局对象global中的成员:

  • console,我们在初体验时,使用了console,它可不是浏览器中的console对象,使用的是node中的console
  • process,和进程相关的对象
  • setInterval,同理,也是node中的,不是浏览器中的
  • require(),它是全局对象global中的一个方法,用于在js文件中引入另外的文件
  • __dirname,当前执行文件的绝对路径(在js文件中使用)
  • __filename,当前执行文件的绝对路径,包含文件名(在js文件中使用)

console

用于输出。功能与浏览器中的console功能类似。

process

process.argv

包含命令行参数的数组。第一个元素会是’node’,第二个元素将是.js文件的名称,接下来的参数依次是命令行参数。

node index.js a=1 b=2

process.env

获取当前系统环境信息的对象,常规可以用来进一步获取环境变量、用户名等系统信息

process.platform

获取运行程序所在的平台系统 ‘darwin’, ‘freebsd’, ‘linux’, ‘sunos’ or ‘win32’

process.execPath

获取开启当前进程的执行文件的绝对路径

__dirname , __filename

注意是下划线。

  • __dirname,当前执行文件的绝对路径

  • __filename,当前执行文件的绝对路径,包含文件名

它们必须是在某个js文件中使用。

nod中的模块

模块是Node.js 平台自带的一套基本的 API(功能模块)。

  1. 如何理解"模块"?
  • 它的功能相对封闭
  • 它是node的内置对象
  • 它是一个个独立的文件
  • 所有模块的源代码 https://github.com/nodejs/node/tree/master/lib
  • 模块的分类
  • 内置模块
    • 下载使用的第三方模块
    • 按node规范自定义模块
  1. 使用模块的基本步骤
    1. 导入模块,格式是:const 模块名 = require("模块名");
    2. 使用模块中的各个功能

path模块

Path:路径。 它提供了我们处理文件,文件夹的路径的工具。

官方手册: http://nodejs.cn/api/path.html

// 使用模块之前,首先加载模块
const path = require('path');

获取文件的文件名

let filename = path.basename(__filename);
console.info(filename)
console.info( path.basename('/a/b/c/d/index.html') )

获取文件的目录名

let dirname = path.dirname(__filename);
console.info(dirname)

获取文件的扩展名

let extname = path.extname(__filename);
console.info(extname)

路径拼接

let p = path.join("a","b")
console.info(p)

其它方法列表

方法 作用
path.basename(path[, ext]) 获取返回 path 的最后一部分(文件名)
path.dirname(path) 返回目录名
path.extname(path) 返回路径中文件的扩展名(包含.)
path.format(pathObject) 将一个对象格式化为一个路径字符串
path.join([…paths]) 拼接路径
path.parse(path) 把路径字符串解析成对象的格式
path.resolve([…paths]) 基于当前工作目录拼接路径

工作目录:当前运行 Node 程序的目录

const path = require('path');

// extname -- 获取文件后缀
console.log(path.extname('index.html')); // .html
console.log(path.extname('index.coffee.md')); // .md

// join -- 智能拼接路径
console.log(path.join('/a', 'b', 'c')); // \a\b\c
console.log(path.join('a', 'b', 'c')); // a\b\c
console.log(path.join('/a', '/b/../c')); // \a\c
console.log(path.join('/a', 'b', 'index.html')); // \a\b\index.html
console.log(path.join(__dirname, 'a', 'index.html')); // 得到一个绝对路径

fs模块

文件操作模块。 Filesystem,提供对文件,文件夹的操作。

手册:http://nodejs.cn/api/fs.html

// 引入模块,引入模块的时候,可以使用var、let,但是建议使用const,因为我们不希望它改变
const fs = require('fs');

fs模块中操作文件(或者文件夹)的方法,大多都提供了两种选择:

  • 同步版本的
  • 异步版本的

文件内容读取 - readFile

异步格式

fs.readFile('文件路径'[,选项], (err, data) => {
    
    
  if (err) throw err;
  console.log(data);
});

说明:

  • 第一个参数:读入的文件路径。 相对路径和绝对路径均可。

  • 第二个参数: 配置项,主要用来配置字符集。可选参数。一般可设置为’utf8’

​ 如果不设置该参数,文件内容会以二进制形式返回。

  • 参数3: 读取完成后触发的回调函数。有两个参数 — err 和 data

    • 读取成功

      • err: null

      • data: 文件内容,如果不设置参数2,则返回二进制数据。可以使用 toString() 方法将二进制数据

        转为正常字符串

      • 读取失败

        • err: 错误对象
        • Data: undefined

示例:

const fs = require("fs")
fs.readFile('文件路径',"utf8", (err, data) => {
    
    
  if (err) throw err;
  console.log(data);
});

异步方法与同步方法

文件写入

覆盖写入 writeFile

const fs = require('fs')

fs.writeFile('./a.txt', 'hello world niahi \n asfsdf', err => {
    
    
  if (err) {
    
    
    console.info(err)
    throw err
  }
})

//向指定文件中写入字符串(覆盖写入), 如果没有该文件则尝试创建该文件

fs.writeFile(var1, var2, var3, var4);

参数1: 要写入的文件路径 — 相对路径和绝对路径均可,推荐使用绝对路径

参数2: 要写入文件的字符串

参数3: 配置项,设置写入的字符集,默认utf-8

参数4: 写入完成后触发的回调函数,有一个参数 — err (错误对象)

文件追加 appendFile

const fs = require('fs')

fs.appendFile('./a.txt', '\n 为天地立命', err => {
    
    
  if (err) {
    
    
    console.info(err)
    throw err
  }
})

//向指定文件中写入字符串(追加写入), 如果没有该文件则尝试创建该文件

fs.appendFile(var1, var2, var3, var4);

参数1: 要写入的文件路径 — 相对路径和绝对路径均可,推荐使用绝对路径

参数2: 要写入文件的字符串

参数3: 配置项,设置写入的字符集,默认utf-8

参数4: 写入完成后触发的回调函数,有一个参数 — err (错误对象)

文件夹操作

状态

创建

删除

调用fs模块的方法,下面列举fs模块中的常用方法

API 作用 备注
fs.access(path, callback) 判断路径是否存在
fs.appendFile(file, data, callback) 向文件中追加内容
fs.copyFile(src, callback) 复制文件
fs.mkdir(path, callback) 创建目录
fs.readDir(path, callback) 读取目录列表
fs.rename(oldPath, newPath, callback) 重命名文件/目录
fs.rmdir(path, callback) 删除目录 只能删除空目录
fs.stat(path, callback) 获取文件/目录信息
fs.unlink(path, callback) 删除文件
fs.watch(filename[, options][, listener]) 监视文件/目录
fs.watchFile(filename[, options], listener) 监视文件
// readFile -- 异步读取文件
fs.readFile('./test.json', (err, data) => {
    
    
    if (err) {
    
    
        console.log('读取文件出错');
    } else {
    
    
        console.log(data); // 读取到的二进制数据
    }
});

fs.readFile('./test.json', 'utf-8', (err, data) => {
    
    
    if (err) {
    
    
        console.log('读取文件出错');
    } else {
    
    
        console.log(data); // 读取到的原始数据
    }
});
// writeFile -- 异步写入文件
fs.writeFile('./abc.html', 'hello world', (err) => {
    
    
    if (err) {
    
    
        console.log('写入文件失败');
    } else {
    
    
        console.log('文件写入成功');
    }
});

querystring模块

查询字符串处理模块

加载模块

const querystring = require('querystring');

调用querystring模块中的方法

// parse -- 将查询字符串解析成JS对象
console.log(querystring.parse('id=1&name=zs&age=20')); 
// { id: '1', name: 'zs', age: '20' }

// stringify -- 将JS对象转成查询字符串
console.log(querystring.stringify({
    
     id: '1', name: 'zs', age: '20' }));
// id=1&name=zs&age=20

url模块

url模块用来处理url地址

一个完整的url 协议://主机地址:[端口]/文件地址?参数

  • 提供两套处理url的API
  • 遗留的API,提供url.parse();方法解析url
  • 新的API,通过实例化URL,来解析url

加载模块

const url = require('url');

遗留API使用方法

let myURL = url.parse('/test.html?id=11&age=22'); // 返回一个包含url各个部分的对象

新的API使用方法,实例化的时候,必须传递一个完整的url

// 直接提供一个完整的url
let myURL = new URL('http://www.xxx.com/test.html?id=11&age=22');
// 或
// 提供两个参数,一是文件路径及参数部分,二是域名,总之,二者组合必须是完整的url
let myURL = new URL('/test.html?id=11&age=22', 'http://www.xxx.com');

// 得到的myURL是一个对象,包含url中的各个部分
// 如果需要解析参数部分,则使用querystring模块,或使用URL的一个子对象searchParams中的get方法
let age = myURL.searchParams.get('age')// 22

http模块

http服务器处理模块

node不同于Apache,安装完node并没有一个能够提供Web服务环境,需要使用http模块自己来搭建Web服务器

http是一个系统模块,让我们能够通过简单的流程创建一个Web服务器


使用http模块搭建Web服务器

创建 Web 服务器的步骤

  • 导入 http 核心模块
  • 创建 server 对象(server 对象负责建立连接,接收数据)
  • 注册 request 事件,当浏览器发送请求到服务器执行,设置处理请求的函数
  • 监听端口(这个步骤也可以放到注册request事件之前)
// 0. 加载 http 核心模块
var http = require('http')
// 1. 创建服务器,得到 Server 实例
var server = http.createServer()
// 2. 监听客户端的 request 请求事件,设置请求处理函数
server.on('request', function (req, res) {
    
    
  // 形参req是请求request的简写
  // 形参res是响应response的简写
  console.log('收到客户端的请求了')
})
// 3. 绑定端口号,启动服务器
server.listen(3000, function () {
    
    
  console.log('Server is running at port 3000.')
})
  • 当服务器接收到浏览器的请求后,如果没有做出响应,浏览器会等待
  • 服务器的最终目的是要根据请求做出响应

如何对浏览器的请求做出响应

当收到浏览器的请求后,会调用处理请求的函数(有两个核心参数 request 和 response)

请求已经能够收到了,现在急需给浏览器的请求做出响应,这里就使用到了处理请求的函数,具体的是使用到了该函数的第二个参数,见下面的代码。

// 代码片段
server.on('request', function (req, res) {
    
    
  // 该函数就是处理请求响应的函数
  // 形参res是响应response的简写
})
  • 形参res
    • 形参res是response的缩写
    • 响应对象,服务器给浏览器返回的响应内容,可以通过该对象设置
    • res.write() 设置响应体(返回给浏览器的内容)的内容,可以多次调用,但是只调用write不会做出响应,发送响应要调用 end()
    • res.end() 把响应报文(响应行、响应头、响应体)发送给浏览器
    • res.setHeader() 设置响应头,比如设置响应体的编码
    • statusCode 设置状态码

PS:浏览器在请求服务器的时候,默认会请求网站根目录下的 /favicon.ico 网站图标

  • 响应代码

    // 0. 加载 http 核心模块
    var http = require('http')
    // 1. 创建服务器,得到 Server 实例
    var server = http.createServer()
    // 2. 监听客户端的 request 请求事件,设置请求处理函数
    server.on('request', function (req, res) {
          
          
        // 设置响应头,设置编码,否则浏览器收到的是乱码
        res.setHeader('Content-Type', 'text/html; charset=utf-8');
        // end中就是返回给浏览器的数据
      	res.end('hello,我是服务器,我收到你的请求了');
    })
    // 3. 绑定端口号,启动服务器
    server.listen(3000, function () {
          
          
      console.log('Server is running at port 3000.')
    })
    
    // 如果需要将一个html页面返回给浏览器,则读取文件,然后返回即可
    
    var http = require('http')
    var fs = require('fs');
    // 1. 创建服务器,得到 Server 实例
    var server = http.createServer()
    // 2. 监听客户端的 request 请求事件,设置请求处理函数
    server.on('request', function (req, res) {
          
          
        fs.readFile('./test.html', (err, data) => {
          
          
            // 如果读取中出现错误,则抛出错误
            if (err) throw err;
            // 没有错误,则返回读取的html,因为html中设置编码,所以这里不需要设置编码
            res.end(data);
        });
    })
    // 3. 绑定端口号,启动服务器
    server.listen(3000, function () {
          
          
      console.log('Server is running at port 3000.')
    })
    

根据不同 url 地址处理不同请求

前面已经可以对浏览器的请求做出响应了,但是响应的内容总是一样的。能不能根据url的不同,做出合适的响应呢?当然可以,那么首先就需要知道浏览器请求的url是什么。

涉及到和请求相关的信息,都是通过请求响应处理函数的第一个参数完成的。

server.on('request', function (req, res) {
    
      
  // 形参req 是 请求request的意思,所有和请求相关的信息,都在req对象中
})
  • 形参req

    • 请求对象,浏览器发送的请求报文中的数据已经被解析到该对象上
    • request.url 获取请求行中的路径
    • request.method 获取请求行中的请求方法
    • request.headers 获取请求头
  • 代码实例

    // 服务器中有3个html文件,分别是a.html b.html c.html
    // 根据浏览器发来的不同的请求,分别返回这三个文件的内容
    
    var http = require('http')
    // 1. 创建服务器,得到 Server 实例
    var server = http.createServer()
    // 2. 监听客户端的 request 请求事件,设置请求处理函数
    server.on('request', function (req, res) {
          
          
        // 根据请求对象req,得到请求url
        let url = req.url;
        if (url === '/a') {
          
          
            // 读取a.html,并通过res.end()响应浏览器的请求
        } else if (url === '/b') {
          
          
            // 读取b.html,并通过res.end()响应浏览器的请求
        } else if (url === '/c') {
          
          
            // 读取c.html,并通过res.end()响应浏览器的请求
        }
    })
    // 3. 绑定端口号,启动服务器
    server.listen(3000, function () {
          
          
      console.log('Server is running at port 3000.')
    })
    

处理浏览器POST方式提交的数据

上一节,我们根据不同的url地址,对不同的请求,做出了不同的响应。但这些请求都是GET方式的请求,如果浏览器使用POST方式向服务器发送了一次请求,又该如何处理呢?

POST请求一般会提交数据给服务器,服务器在接收数据的时候也是分块接收的

var http = require('http')
// 1. 创建服务器,得到 Server 实例
var server = http.createServer()
// 2. 监听客户端的 request 请求事件,设置请求处理函数
server.on('request', function (req, res) {
    
    
    // 假设 /add 是POST方式的请求
    if (req.url === '/add') {
    
    
        // 注册req的data事件,分块接收数据
        let str = '';
        req.on('data', (chunk) => {
    
    
            str += chunk; // chunk 是块的意思,这里将分块接收到的数组拼接到str字符串中
        });
        // 注册req的end事件,当数据都接收到了,会触发end事件
        req.on('end', () => {
    
    
            // 这里处理用户提交的数据
            console.log(str);
        });
    }
})
// 3. 绑定端口号,启动服务器
server.listen(3000, function () {
    
    
  console.log('Server is running at port 3000.')
})

处理静态资源

  • 静态资源指的是html文件中链接的外部资源,如css、js、image文件等等。

  • 如果请求的a.html 文件中链接了外部文件(静态资源),比如css、images、js文件等,浏览器会自动再次发送请求,向服务器请求这些文件

  • 服务器要判断浏览器请求的路径是否是静态资源,如果是静态资源把静态资源的内容返回给浏览器


浏览器请求了静态资源文件,服务器就得做出响应,而且还要指定响应数据的类型,否则浏览器会把字符串当做纯文本处理。

建议每个响应都告诉客户端我给你发送的 Content-Type 内容类型是什么

为不同的文件类型设置不同的 Content-Type

  • .html:text/html
  • .css:text/css
  • .js:application/javascript
  • .jpg:image/jpg
response.setHeader('Content-Type', 'text/css');

处理 404

  • 404是一个响应状态码,表示请求的资源不存在

  • 如果请求未处理的路径,服务器不会做任何的响应,此时浏览器处于等待状态

  • 如果浏览器请求未处理的路径,统一设置响应码 404,并做友好提示

    // 设置状态码为404
    response.statusCode = 404;
    response.end('对不起,您请求的页面未找到');
    

留言板案例

ajax学习中,做过这个案例。当时使用的是老师提供的接口来完成的。现在,学习了node,我们自己来处理浏览器的请求。

此次开发,使用不使用ajax无所谓,关键是如何来处理浏览器的请求

准备工作

  1. 新建一个文件夹,比如msg
  2. 将使用到的html文件、css文件、图片文件、js文件等复制到准备好的文件夹msg中
  3. 将模拟数据db.json文件复制到msg中
  4. 在msg文件夹中,创建app.js,搭建Web服务环境

实现留言列表

  • 当输入地址,回车,会向服务器发送一次GET请求
  • 服务器接收到请求,要给浏览器返回它要的数据
    在这里插入图片描述
  • 在这里插入图片描述

实现添加留言功能

在这里插入图片描述

  • 点击界面中的“添加”时,向服务器发送请求,并提交数据给服务器,注意设置表单的action和method
  • 服务器接收到请求,完成数据添加,并作出响应,告知浏览器添加成功与否

猜你喜欢

转载自blog.csdn.net/weixin_45176415/article/details/104408235