node.js 学习笔记(一) 基础知识

node.js 学习笔记(一) 基础知识

一、Node.js是什么

       Node.js 不是一门语言,不是库不是框架, 是一个 JavaScript 运行时的环境,可以解析和执行 JavaScript 代码,以前只有浏览器可以解析执行JavaScript代码,现在的 JavaScript 可以脱离浏览器来执行。构建于 Chrome V8 引擎之上

node中的 JavaScript:

  • 没有BOM、DOM
  • ES语法
  • 在 node 这个 JavaScript 执行环境中为 JavaScript 提供了一些服务器级别的操作API,如:
    • 文件读写
    • 网络服务的构建
    • 网络通信
    • http服务器

       node.js 使用事件驱动(event-driven)、非阻塞IO模型(异步)(non-blocking I/O model)来达到轻量和高效的效果。npm 是世界上最大的开源库生态系统

       

二、Node.js 的应用

  • Web 服务后台
  • 命令行工具
    • npm(node开发)
    • git
    • hexo(node开发)

       

三、使用node.js

3.1 使用 node.js 执行 js 脚本

步骤:

  1. 正常的编写 js 脚本文件
  2. 在脚本文件的根目录下打开 cmd,输入 node + 文件名

注意:文件名不要使用 node.js 命名

例子:

var mes = 'hello world!'
console.log(mes);

3.2 使用 node.js 读写文件

浏览器中的 JavaScript 是没有文件操作能力的,但 Node 中的 JavaScript 具有文件读写能力。在 Node 中如果想要进行文件操作,那么就要引入 fs 这个核心模块,其提供了所有文件操作相关的API。

3.2.1 读取文件

读取文件:fs.readFile(), 其有两个参数,第一个参数是要读取的文件路径,第二个参数是回调函数:

  • error:
    • 若读取失败,error就是错误对象
    • 若读取成功,error就为null
  • data:
    • 若读取失败,data 就是 undefined
    • 若读取成功,data 就是读取的数据
// fs 是 file-system 的意思 文件系统
// 1. 使用require方法加载fs核心模块
let fs = require('fs');

// 2. 读取文件
fs.readFile('./hello.txt',function (error, data) {
    
    
  if(error) {
    
    
    console.log('读取文件失败');
  } else {
    
    
    console.log(data);
  }
})

注意:文件中存储的其实是二进制数据,但这里看到的却不是0 和 1,是因为二进制转为了16 进制,可以通过toString()方法转换为我们认识的字符

// 1. 使用require方法加载fs核心模块
let fs = require('fs');

// 2. 读取文件
fs.readFile('./hello.txt',function (error, data) {
    
    
  if(error) {
    
    
    console.log('读取文件失败');
  } else {
    
    
    console.log(data.toString());
  }
})

3.2.2 写文件

写文件:fs. writeFile(),有三个参数:文件路径、文件内容和回调函数(只有error一个形参)

fs.writeFile('./hello.txt', '大家好呀!!', function (error) {
    
    
  if (error) {
    
    
    console.log('写入失败')
  } else {
    
    
    console.log('写入成功');
  }
});

3.3 使用 node.js 提供 http 服务

       可以使用 node 轻松的构建一个 web 服务器,node 中提供的核心模块:http,辅助创建服务器

步骤:

  1. 加载 http 核心模块
  2. 使用 http.createServer() 方法创建一个 web 服务器,返回一个 Server 实例
  3. 服务器接收请求,接收到请求后自动触发 request 请求事件,执行回调函数对请求进行处理,并发送响应
  4. 绑定端口号,启动服务器,监听是否有请求

要点:

  • 一个请求对应一个响应,如果在一个请求的过程中,已经结束响应了,则不能重复发送响应
  • 没有请求就没有响应

基本格式:

//1. 加载http核心模块
let http = require('http');

//2. 使用http.createServer()方法创建一个web服务器
let server = http.createServer();

//3. 服务器接收请求,接收到请求后自动触发request请求事件,执行回调函数
server.on('request',function(req,res) {
    
    
  ...
})

//4. 绑定端口号,启动服务器
server.listen(3000,function() {
    
    
  ...
});

简写格式:

let http = require('http');

http
  .createServer(function (req, res) {
    
    
    ...
  })
  .listen(3000, function () {
    
    
    ...
  })

3.3.1 request 请求事件

request请求事件处理函数接收两个参数:

  • Request 请求对象:用来获取客户端的一些请求信息,例如请求路径
  • Response 响应对象:用来给客户端发送响应信息。有一个方法:**write()**用来给客户端发送响应信息,write 可以使用多次,但是最后一次一定要使用 end 来结束响应,一次性把所有响应内容呈现给客户端,否则客户端会一直等待。

3.3.2 案例

案例1:

//1. 加载http核心模块
let http = require('http');

//2. 使用http.createServer()方法创建一个web服务器
let server = http.createServer();

//3. 服务器接收请求,接收到请求后自动触发request请求事件,执行回调函数
server.on('request',function(req,res) {
    
    
  console.log('收到客户端请求');
})

//4. 绑定端口号,启动服务器
server.listen(3000,function() {
    
    
  console.log("服务器启动成功,可通过 http://127.0.0.1:3000/ 来访问");
});
访问 http://127.0.0.1:3000/ 后 命令行界面:

案例2:

在案例1的基础上进一步添加请求处理和发送响应的功能:

//1. 加载http核心模块
let http = require('http');

//2. 使用http.createServer()方法创建一个web服务器
let server = http.createServer();

//3. 服务器接收请求,接收到请求后自动触发request请求事件,执行回调函数
server.on('request',function(request,response) {
    
    
  console.log('收到客户端请求, 请求路径是:' + request.url);

  //response
  response.write('hello');
  response.write(' node.js');
  response.end(); 
})

//4. 绑定端口号,启动服务器
server.listen(3000,function() {
    
    
  console.log("服务器启动成功,可通过 http://127.0.0.1:3000/ 来访问");
});

服务器端:

客户端:

注意:

  1. 修改代码后,需要重启node才会生效

  2. 以上的代码针对不同的路径都响应同样的内容,而实际开发中一定是不同的请求响应不同的内容

       

三、Node中的 JS 模块

3.1 模块系统

要点:

  • 在 node 中,只能通过 require 方法来加载执行多个 JavaScript 脚本文件

  • require 就是一个方法,有两个作用:

    1. 用来加载执行模块的代码
    2. 拿到被加载文件模块导出的接口对象
  • 自定义模块中require方法中的相对路径必须加 ./,不能省略否则会报错,因为去掉./后node就会把该模块当成核心模块

  • 在 node 中,没有全局作用域,只有模块作用域,外部访问不到内部,内部也访问不到外部

       

3.2 核心模块

       Node 为 JavaScript 提供了很多服务器级别的 API,这些API绝大多数都被包装到一个具名的核心模块中了。例如文件操作的 fs模块,http 服务构建的 http模块…

想要使用核心模块,必须要用 require 引入,如:

const fs = require('fs');

       

3.3 用户自定义模块

案例:简单的自定义模块化

// 这是 a.js 文件
var foo = 'aaa';
console.log('a start');
require('./b.js'); // ./不能省略
console.log('a end');
console.log(foo)
// 这是 b.js 文件
var foo = 'bbb';
console.log('bbbbb');

执行a.js 后,结果为:

a start
bbbbb
a end
aaa //没有全局作用域,不同模块中后面同名变量的值不会覆盖当前模块中同名变量的值

       在 node 中,没有全局作用域,只有模块作用域,外部访问不到内部,内部也访问不到外部。但我们时常希望访问其他模块中的成员和方法,怎么解决呢???

解决方案见3.4

       

3.4 模块的加载与导出

       在每个文件模块中都提供了一个对象:exports,默认是一个空对象把所有需要被外部访问的成员都挂载到 exports 对象中

案例:

// 这是 a.js 文件
// 得到 b 的exports 对象,不是其中的某一个成员或方法
let bExports = require('./b.js'); 
console.log(bExports.foo); // hello
console.log(bExports.add(10,30)) //40
// 这是 b.js 文件
var foo = 'hello';

//左边的foo是exports中的成员键值,右边的foo是b.js模块中的变量
exports.foo = foo; 

exports.add = function(x,y) {
    
    
    return x + y;
}
function add(x,y) {
    
    
    return x - y;
}

       

四、IP地址和端口号

  • IP 地址用来定位计算机
  • 端口号用来定位具体的应用程序(进程)
  • 一切需要联网通信的软件都会占用一个端口号
  • 端口号范围从0~65536 之间
  • 可以同时开启多个服务,但一定要确保不同服务占用的端口号不一致才可以

       

4.1 相应响应类型Content-Type

       在服务器端默认发送的数据其实是 utf-8 编码的内容,但浏览器并不知道是utf-8编码的内容,就会按照当前操作系统的默认编码(gbk)去解析,解决方法:告诉浏览器服务器发送的内容是什么编码形式的,使用 content-Type 来告知浏览器发送的数据是什么类型

let http = require('http');

let server = http.createServer();

server.on('request',function(req,resp) {
    
    
    res.setHeader('Content-Type','text/plain;charset=utf-8');
    res.end('hello 世界');
})

server.listen(3000,function() {
    
    
  console.log("服务器启动成功!");
});

       

4.2 通过网络发送文件

let http = require('http');
let fs = require('fs');

let server = http.createServer();

server.on('request',function(req,resp) {
    
    
    fs.readFile('./resource/index.html',function(err,data) {
    
    
        if(err) {
    
    
            res.setHeader('Content-Type','text/plain;charset=utf-8');
            res.end('文件读取失败,请稍后重试!')
        } else {
    
    
            res.setHeader('Content-Type','text/html;charset=utf-8');
            res.end(data);
        }
    })
})

server.listen(3000,function() {
    
    
  console.log("服务器启动成功!");
});

要点:

  1. 若 res.end() 中的字符串里满足 html 标签格式,虽然返回的是字符串,但浏览器会将其作为标签来解析。加上res.setHeader(‘Content-Type’,‘text/plain;charset=utf-8’);后就会当成普通文本来处理
  2. 查询不同资源对应的 content-type 的网址:http://tool.oschina.net/

猜你喜欢

转载自blog.csdn.net/weixin_45950819/article/details/121109522
今日推荐