node.js

Node.js

**Node.js简介:**Node.js的实质是一个运行在服务器的Javascript。即一个基于Chrome Javascript运行时建立的一个平台。

**Node.js特点:**是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎。

**第一个Node.js程序:**Hello Node.js

console.log("Hello Node.js");

在控制台输入:node回车,进入交互模式:>console.log(“Helol Node.js”);

或者保存文件名为HelloNode.js,利用node HelooNode.js命令都可执行console.log函数将信息输出到控制台或终端。

了解最基础的输出方式,现在来创建第一个应用。(不建议用记事本编写,因为Node.js只支持UTF-8编码,容易出现乱码,在此推荐用Sublime Text3:https://www.iplaysoft.com/sublimetext.html)

步骤:

**一:**利用sublime建立项目文件:HelloNode.js

进入代码书写:

设置变量http,将node.js自带的http模块赋值给此变量

var http=require('http');



//请求(require)node.js自带的http模块,并赋值给http变量

调用createServer方法,用于建立http服务器,并调用listen()方法设置端口号

http.createServer(function(request,response){
  //发送HTTP头部
  response.writeHead(200,{'Content-Type': 'text/plain'});
  //发送响应数据:Hello Node.js!
  response.end('Hello Node.js!\n');
}).listen(8888);
//打印log信息
console.log('Server running at http://127.0.0.1:3000/');

编码结束。

二:运行本地服务器

控制台进入HelloNode.js所在根目录,执行:node HelloNode.js命令,终端打印:console.log信息后,在浏览器输入http地址及端口:http:\127.0.0.1:3000;

模块


在JavaScript中,每个JavaScript文件都被当做一个模块使用,而我们也可以通过npm从网上下载所要依赖的模块

模块的调用


常用模块的调用

在node.js中,我们经常会使用调用模块来实现各种功能,我们看看node.js官网的一段创建服务器的代码

const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});
server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

在第一行中就使用了require来引入所需要的http模块,然后在下面就通过http的createServer方法来创建一个服务器,上面的服务器使用node命令就可以启动了。

JavaScript文件的调用

调用当前项目下的JavaScript文件,理所当然是需要写入路径的,假设我们项目有当前路径如下图

img

在两个文件中写入对应的代码,在index.js中调用main.js

//index.js
const main = require('./main');
console.log(main.a);
//main.js
var a = 2;
exports.a = a;

require和exports


require

在node中,通过使用require来调用其他模块,这些模块可以分为两种情况,放在node_moudles文件夹中的模块和其他路径下的模块。

对于require来说,如果在其后的括号内的路径不是以./开头,就会默认调用其父级文件夹中的node_moudles文件夹中的模块或是node安装位置的node_moudles文件夹中的模块。如上面调用http模块,或是调用使用npm导入的connect模块。

const http=require('http');



const connect=require('connect');

除了父级文件夹中和node安装位置的node_moudles文件夹外,其他文件都不会是这种写法的调用对象。

而如果要调用的文件是依据于当前的文件路径而定的话,就使用./为开头来调用,这里的“./”是表明了和当前文件处于同一文件夹下的文件,如上面提及的index.js文件和main.js文件处于同一文件夹下,就可以使用require("./main.js");(这里的“.js”可以省略)

exports

exports用于将当前文件/模块的内容暴露给其他文件,exports可以当前是一个对象,举个例子

假设当前index.js和test.js在同一文件夹下

// index.js
const test = require('./test');
console.log(test.a);
console.log(test.b);
console.log(test.c);
// test.js
var a = 1;
var b = 2;
var c = 3;
exports.a = a;
exports.b = b;
//运行index.js结果
// 1
// 2
// undefined

这里test.js将变量a,b两个变量交由exports暴露出去,然后index.js调用该模块,调用的test为一个对象,属性即为exports暴露出的变量,实际上也可以为方法。

这里的exports.后面跟着的属性名是可以自由定义的,但一般和对应的变量名或者方法名相同。

如果要暴露出一个构造方法或一个类,使用module.exports来暴露更为合适,同样举个例子

假设index.js和Person.js在同一文件夹下

//Person.js
//构造方法
function Person(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
}
Person.prototype.sayHello = function() {
    console.log(`我叫 ${this.name} ,我今年${this.age}岁,我是${this.sex}的`);
}
//类
class Person {
    constructor(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    sayHello() {
        console.log(`我叫 ${this.name} ,我今年${this.age}岁,我是${this.sex}的`);
    }
}
module.exports = Person;
//index.js
const Person = require('./Person');
var p = new Person('夏明', 20, '男');
p.sayHello();
//我叫 夏明 ,我今年20岁,我是男的

本来如果使用exports来暴露方法的话,方法就会变为赋值对象的方法了,即上面index.js文件中Person的一个方法,而通过使用module.exoprts就将对象直接变为对应的方法,用下面使用exports暴露的代码来区别一下

//Person.js
function Person(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
}
Person.prototype.sayHello = function() {
    console.log(`我叫 ${this.name} ,我今年${this.age}岁,我是${this.sex}的`);
}
exports.Person = Person;
//index.js
const Person = require('./Person');
var p = new Person.Person('夏明', 20, '男');
p.sayHello();
//我叫 夏明 ,我今年20岁,我是男的

fs 模块

fs 模块提供类似 UNIX 标准的 文件操作 API,其中所有的方法均有 异步同步 版本

在一般情况下,异步方法性能更高,所以下面只会介绍常用的异步方法

(1)通用操作

① 获取信息:stat(path, callback)

  • path:路径

  • callback:回调函数,接收两个参数,分别是

    Error
    

    对象和

    fs.stats
    

    对象,

    stats
    

    对象的常用方法如下:

    • isFile():如果是文件返回 true,否则返回 false
    • isDirectory():如果是目录返回 true,否则返回 false
    • isBlockDevice():如果是块设备返回 true,否则返回 false
    • isCharacterDevice():如果是字符设备返回 true,否则返回 false
    • isSymbolicLink():如果是软链接返回 true,否则返回 false
    • isFIFO():如果是 FIFO 返回true,否则返回 false
    • isSocket():如果是 Socket 返回 true,否则返回 false
const fs = require('fs')
fs.stat('input.txt', function (err, stats) {
	if (err) {
        return console.error(err)
    }
    // 检测文件类型
    console.log(stats.isFile())
    console.log(stats.isDirectory())
})
123456789

(2)文件操作

① 打开文件:open(path, flags[, mode], callback)

  • path:文件路径
  • flags:文件打开方式,它的取值如下:
    • r:以读取模式打开文件,如果文件不存在则抛出异常
    • r+:以读写模式打开文件,如果文件不存在则抛出异常
    • rs:以同步的方式读取文件
    • rs+:以同步的方式读取和写入文件
    • w:以写入模式打开文件,如果文件不存在则创建文件
    • wx:类似于 w,但是如果文件存在,那么文件写入失败
    • w+:以读写模式打开文件,如果文件不存在则创建文件
    • wx+:类似 w+,但是如果文件存在,那么文件读写失败
    • a:以追加模式打开文件,如果文件不存在则创建文件
    • ax:类似 a, 但是如果文件存在,那么文件追加失败
    • a+:以读取追加模式打开文件,如果文件不存在则创建文件
    • ax+:类似 a+,但是如果文件存在,那么文件读取追加失败
  • mode:文件权限,创建文件的默认权限为 0666
  • callback:回调函数,接收两个参数,分别是错误信息和文件描述符

② 关闭文件:close(fd, callback)

  • fd:文件描述符
  • callback:回调函数,没有参数
const fs = require('fs')
// 打开文件
fs.open('file.txt', 'r+', function(err, fd) {
    if (err) {
    	return console.error(err)
    }
    console.log('文件打开成功')
    // 关闭文件
    fs.close(fd, function(err) {
        if (err) {
        	console.error(err)
        } 
        console.log('文件关闭成功')
    })
})
123456789101112131415

③ 写入文件:writeFile(file, data[, options], callback)

  • file:文件路径或文件描述符
  • data:要写入文件的数据,可以是 StringBuffer 对象
  • options:配置对象,包含三个属性,分别如下:
    • encoding:文件编码,默认为 utf8
    • mode:文件权限,默认为 0666
    • flag:文件打开方式,默认为 w
  • callback:回调函数,接收一个参数,就是错误信息
const fs = require('fs')
var data = 'Hello World'
// 写入文件
fs.writeFile('file.txt', data, function(err) {
    if (err) {
  		return console.error(err)
    }
    console.log('文件写入成功')
})
123456789

④ 读取文件:read(fd, buffer, offset, length, position, callback)

  • fd:文件描述符
  • buffer:数据写入的缓冲区
  • offset:缓冲区的写入偏移量
  • length:文件读取的字节数
  • position:文件读取的起始位置,如果为 null,则会从当前文件指针的位置读取
  • callback:回调函数,接收三个参数,分别是错误信息、读取字节数和缓冲区对象
const fs = require('fs')
var buf = new Buffer.alloc(1024)
// 打开文件
fs.open('file.txt', 'r+', function(err, fd) {
    if (err) {
        return console.error(err)
    }
    // 读取文件
    fs.read(fd, buf, 0, buf.length, 0, function(err, bytes) {
        if (err) {
        	console.error(err)
        }
        if (bytes > 0) {
            var data = buf.slice(0, bytes).toString()
        	console.log(data)
        }
    })
})
123456789101112131415161718

⑤ 截取文件:ftruncate(fd, len, callback)

  • fd:文件描述符
  • len:截取长度
  • callback:回调函数,没有参数
const fs = require('fs')
var buf = new Buffer.alloc(1024)
// 打开文件
fs.open('file.txt', 'r+', function(err, fd) {
    if (err) {
    	return console.error(err);
    }
    // 截取文件
    fs.ftruncate(fd, 10, function(err) {
        if (err){
        	console.error(err)
        }
        console.log('文件截取成功')
    })
})
123456789101112131415

⑥ 删除文件:unlink(path, callback)

  • path:文件路径
  • callback:回调函数,没有参数

(3)目录操作

① 创建目录:mkdir(path[, options], callback)

  • path:文件路径
  • options:配置信息,它的取值如下:
    • recursive:是否以递归的方式创建目录,默认为 false
    • mode:目录权限,默认为 0777
  • callback:回调函数,没有参数

② 删除目录:rmdir(path, callback)

  • path:文件路径
  • callback:回调函数,没有参数

③ 读取目录:readdir(path, callback)

  • path:文件路径
  • callback:回调函数,接收两个参数,分别是错误信息和目录下的文件数组
const fs = require('fs')
// 读取目录
fs.readdir('./', function(err, files) {
    if (err) {
    	return console.error(err);
    }
    files.forEach(function (file) {
    	console.log(file)
    })
})
12345678910

(4)管道 Stream

Stream 是一个 抽象接口,Node 中很多对象都实现了这个接口

① 管道类型

Stream 对象共有四种类型,分别如下:

  • Readable:可读
  • Writable:可写
  • Duplex:可读可写
  • Transform:操作被写入数据,然后读出结果

② 管道事件

所有的 Stream 对象都是 EventEmitter 的实例,常用的绑定事件如下:

  • data:当有数据可读时触发
  • end:当没有数据可读时触发
  • finish:当所有数据都被写入时触发
  • error:在接收和写入过程中发生错误时触发

③ 读取 Stream

const fs = require('fs')
var data = ''
// 创建可读流
var readerStream = fs.createReadStream('input.txt')
// 设置编码
readerStream.setEncoding('UTF8')
// 处理流事件(data、end、error)
readerStream.on('data', function(chunk) {
   data += chunk
})
readerStream.on('end', function() {
   console.log(data)
})
readerStream.on('error', function(err) {
   console.log(err.stack)
})
12345678910111213141516

④ 写入 Stream

const fs = require('fs')
var data = 'Hello World'
// 创建可写流
var writerStream = fs.createWriteStream('output.txt')
// 写入数据
writerStream.write(data, 'UTF8')
// 标记文件末尾
writerStream.end()
// 处理流事件(finish、error)
writerStream.on('finish', function() {
    console.log('Finished')
})
writerStream.on('error', function(err){
   console.log(err.stack)
})
123456789101112131415

⑤ 管道流

管道流用于从一个流传递数据到另一个流

const fs = require('fs')
// 创建可读流
var readerStream = fs.createReadStream('input.txt')
// 创建可写流
var writerStream = fs.createWriteStream('output.txt')
// 读取 input.txt 文件内容,并将内容写入 output.txt 文件
readerStream.pipe(writerStream)
1234567

⑥ 链式流

链式流一般用于管道,可以理解成多个管道相连

const fs = require('fs')
const zlib = require('zlib')
// 压缩 input.txt 文件为 input.txt.gz
fs.createReadStream('input.txt')
  .pipe(zlib.createGzip())
  .pipe(fs.createWriteStream('input.txt.gz'))
// 解压 input.txt.gz 文件为 input.txt
fs.createReadStream('input.txt.gz')
  .pipe(zlib.createGunzip())
  .pipe(fs.createWriteStream('input.txt'))

path 模块

path 模块提供 处理文件路径的工具,常用的属性和方法如下:

  • sep:平台的文件路径分隔符,可以是 \\/
  • delimiter:平台的分隔符,可以是 ;:
  • posix:以 posix 兼容的方式提供 path 方法
  • win32:以 win32 兼容的方式提供 path 方法
  • normalize(path):规范化路径
  • dirname(path):返回路径中的文件夹名称
  • basename(path):返回路径中的文件名称
  • extname(path):返回路径中的文件后缀名
  • parse(pathString):从字符串中返回路径对象
  • format(pathObject):从对象中返回路径字符串
  • isAbsolute(path):判断是否为绝对路径
  • relative(from, to):基于 from 将 to 从绝对路径转换为相对路径
  • path.join([path1],[path2] ... [pathN]):连接路径
const path = require('path')
const home = 'D:\\Blog\\source\\_posts'

console.log(path.sep)
console.log(path.delimiter)
console.log(path.posix)
console.log(path.win32)

console.log(path.dirname(home))
console.log(path.basename(home))
console.log(path.extname(home))

console.log(path.isAbsolute(home))
console.log(path.relative('D:\\Blog\\public', home))

console.log(path.join(home,  fs、path模块'))
fetch方法:

简单的了解了Promise后我们就可以对fetch()方法有一个很好的认识了,fetch是全局量window的一个方法,第一个参数为URL。

// url (必须), options (可选)
fetch('/some/url', {
    method: 'get'
}).then(function(response) {

}).catch(function(err) {
    // 出错了;等价于 then 的第二个参数,但这样更好用更直观 :(

});
123456789

url参数是必须要填写的,option可选,设置fetch调用时的Request对象,如method、headers等
比较常用的Request对象有:

  • method - 支持 GET, POST, PUT, DELETE, HEAD
  • url - 请求的 URL
  • headers - 对应的 Headers 对象
  • body - 请求参数(JSON.stringify 过的字符串或’name=jim\u0026age=22’ 格式)

如提交JSON示例如下:

fetch('/users.json', {
    method: 'POST', 
    body: JSON.stringify({
        email: 'huang@163.com'
        name: 'jim'
    })

}).then(function() { /* 处理响应 */ });
12345678
Response响应

fetch方法的then会接收一个Response实例,值得注意的是fetch方法的第二个then接收的才是后台传过来的真正的数据,一般第一个then对数据进行处理等。

例如fetch处理JSON响应时 回调函数有一个json()方法,可以将原始数据转换为json对象

fetch('/some/url', { method: 'get', })
    // 第一个then  设置请求的格式
        .then(e => e.json())
        // 第二个then 处理回调
        .then((data) => {
         <!-- data为真正数据 -->
    }).catch(e => console.log("Oops, error", e))
1234567
使用fetch请求发送cookie
fetch(url,{
credentials:"include"
})

通过fetch方法获取的数据 循环遍历添加到tbody中 数据就可以显示啦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值