07nodejs

node.js

介绍

是什么
    node.js是一个开发平台,有对应的编程语言,在语言运行时,有实现特有功能的API
    该平台使用的编程语言为JavaScript语言
    node.js 平台是基于 Chrome V8 JavaScript 引擎构建。
    基于 node.js 可以开发控制台程序(命令行程序、CLI程序)、桌面应用程序(GUI)(借助 node-webkit、electron 等框架实现)、Web 应用程序(网站)

特点:
	事件驱动(当事件被触发时,执行传递过去的回调函数)
    非阻塞 I/O 模型(当执行I/O操作时,不会阻塞线程)
    单线程
    拥有世界最大的开源库生态系统 —— npm。

node.js网站
	官方网站:https://nodejs.org/
	中文网站:http://nodejs.cn/
	中文社区:https://cnodejs.org/
	API:http://nodejs.cn/api/
	第三方npm:https://www.npmjs.com/
	
nodejs开发web应用程序和PHP、java、ASP.Net等传统模式开发的区别
	传统模式:
		必须要有web容器
		在web容器里面写具体的动态页面
	nodejs: 
		没有web容器,本身就是一个http服务器
		每个请求后都必须自己写代码去处理,如果不写代码处理这个请求就不会处理

REPL

REPL全称: Read-Eval-Print-Loop(交互式解释器)
    R 读取 读取用户输入,解析输入了Javascript 数据结构并存储在内存中。 
    E 执行 执行输入的数据结构 
    P 打印 输出结果 
    L 循环 循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出。 
在REPL中编写程序
	类似于浏览器开发人员工具中的控制台功能
	直接在控制台输入node命令进入REPL环境 
退出
	输入.exit
	按住Ctrl键不要放开, 然后按两下c键

JavaScript 文件名命名规则

不要用中文
不要包含空格
不要出现node关键字
建议以 '-' 分割单词

文件操作

写文件

// 实现文件写入操作
// 加载文件操作模块,fs模块
// fs 模块,在使用的时候,必须通过 require() 函数来加载该模块, 方可使用 var fs = require('fs');
//  fs 模块不是全局模块,非全局模块需要先通过 require('') 加载该模块
var fs = require('fs');
// 实现文件写入操作
var msg = 'hello,world,你好世界!';
// 调用fs.writeFile进行文件写入
// fs.writeFile(file, data[, options], callback)
fs.writeFile('./hello.txt', msg, 'utf-8', function (err) {
    // 如果err = null表示写入成功
    if (err) {
        console.log('写文件错误' + err);
    }else {
        console.log('ok');
    }
});

读文件

// 实现文件读操作
// 加载文件操作模块,fs模块
var fs = require('fs');
// 调用fs.readFile进行文件读取
// fs.readFile(path[, options], callback)
fs.readFile('./hello.txt', function (err,data) {
    // 如果err = null表示读取成功
    if (err) {
        console.log('写文件错误' + err);
    }else {
        // 当options不传入编码,data默认为字节数组
        // 字节数组转字符串
        // 默认为utf-8,可写可不写
        console.log(data.toString("utf-8"));
    }
});

// 当传入编码data,默认data从buffer转为string
fs.readFile('./hello.txt', 'utf-8', function (err,data) {
    // 如果err = null表示读取成功
    if (err) {
        console.log('写文件错误' + err);
    }else {
        console.log(data);
    }
});

// 读文件路径问题
// ./hello.txt 相当于在哪执行nodejs命令,就在哪个目录下查找文件
// 例如在c盘下执行nodejs命令,读取路径就为C:\hello.txt
// 在 D:\Web\10nodejs下执行nodejs,读取路径为 D:\Web\10nodejs\hello.txt
// 解决在文件读取中./相对路径问题
// __dirname: 表示当前正在执行的js文件所在的目录
// __filename: 表示当前正在执行的js文件的完整路径

// 拼接文件路径
// 对于不同操作系统反斜杠不同,且__dirname可能存在反斜杠,操作不方便
// var filename = __dirname + '\\' + 'hello.txt';
// path解决路径拼接问题
var path = require('path');
var filename = path.join(__dirname, 'hello.txt');

fs.readFile(filename, 'utf-8', function (err,data) {
    // 如果err = null表示读取成功
    if (err) {
        console.log('写文件错误' + err);
    }else {
        console.log(data);
    }
});

创建文件目录

// 创建文件目录
var fs = require('fs');
// fs.mkdir(path[, options], callback)
fs.mkdir('text-mkdir',function (err) {
    if (err){
        console.log('创建目录失败,详细信息如下:');
        console.log(err);
    }else {
        console.log('目录创建成功');
    }
})

编写http服务程序

// 加载http模块
var http = require('http');
// 创建http服务
var server = http.createServer();
// 监听用户请求事件(request事件)
// 请求报文——request  req
// 响应数据——response res
server.on('request', function (req, res) {
    // 解决乱码:服务器通过设置响应报文头,告诉浏览器使用相应的编码来解析
    res.setHeader('Content-Type','text/plain; charset=utf-8');  //告诉浏览器发送的为纯文本,通过utf-8来解析
    // 服务器给与响应
    res.write('hello world 你好世界');

    //告诉浏览器发送的为html,通过utf-8来解析
    // res.setHeader('Content-Type','text/html; charset=utf-8');
    // res.write('hello world <h1>你好世界</h1>');

    // 对于每一个请求服务器必须结束响应,否则浏览器会一直等待服务器响应
    res.end();
});
// 启动服务
server.listen(80, function () {
    console.log('服务器启动了,请访问...')
})
// 加载http模块
var http = require('http');
// 创建http服务 默认当用户请求服务的时候执行
http.createServer(function (req, res) {
    res.setHeader('Content-Type','text/plain; charset=utf-8');
    // 获取用户请求路径req.url
    // 通过不同的请求路径,服务器做出不同的相应
    if (req.url === '/' || req.url === '/index'){
        // 把数据发送给浏览器,之后终止
        // res.write('hello index');
        // res.end();
        res.end('hello index');
    }else if (req.url === '/login'){
        res.end('hello login');
    }else {
        res.end('404,not Found 客户端错误');
    }
}).listen(80, function () {
    console.log('服务器启动了,请访问...')
})
// 创建http服务程序

// 加载path模块
var path = require('path');
// 加载fs模块
var fs = require('fs');
// 加载http模块
var http = require('http');
// 创建http服务 默认当用户请求服务的时候执行
http.createServer(function (req, res) {
    // 获取用户请求路径req.url
    // 通过不同的请求路径,服务器做出不同的相应
    if (req.url === '/' || req.url === '/index'){
        var filename = path.join(__dirname, 'https', 'index.html');
        fs.readFile(filename, function (err,data) {
            // 如果err = null表示读取成功
            if (err) {
                console.log('写文件错误' + err);
            }else {
                res.end(data);
            }
        });
    }else if (req.url === '/images/index.png'){   // 设置图片路径
        var filename = path.join(__dirname, 'images', 'index.png');
        fs.readFile(filename, function (err,data) {
            // 如果err = null表示读取成功
            if (err) {
                console.log('写文件错误' + err);
            }else {
                res.setHeader('Content-Type','image/png');
                res.end(data);
            }
        });
    }else if (req.url === '/css/index.css'){   // 设置图片路径
        var filename = path.join(__dirname, 'css', 'index.css');
        fs.readFile(filename, function (err,data) {
            // 如果err = null表示读取成功
            if (err) {
                console.log('写文件错误' + err);
            }else {
                res.setHeader('Content-Type','text/css');
                res.end(data);
            }
        });
    } else if (req.url === '/login'){
        var filename = path.join(__dirname, 'https', 'login.html');
        fs.readFile(filename, function (err,data) {
            // 如果err = null表示读取成功
            if (err) {
                console.log('写文件错误' + err);
            }else {
                res.end(data);
            }
        });
    }else {
        var filename = path.join(__dirname, 'https', '404.html');
        fs.readFile(filename, function (err,data) {
            // 如果err = null表示读取成功
            if (err) {
                console.log('写文件错误' + err);
            }else {
                res.end(data);
            }
        });
    }
}).listen(80, function () {
    console.log('服务器启动了,请访问...')
})

模拟Apache

// 加载path模块
var path = require('path');
// 加载fr模块
var fs = require('fs');
// 加载http模块
var http = require('http');
// 加载第三方模块mime
var mime = require('mime');


// 创建服务
http.createServer(function (req, res) {
    // 获取用户请求的路径 req.url
    // 获取public目录的完整路径
    // var publicDir = path.join(__dirname, 'public');
    // 根据public的路径和用户请求的路径最终计算出用户请求的静态资源的完整路径
    // var filrname = path.join(publicDir, req.url);

    // 获取完整路径
    var filrname = path.join(__dirname, 'public', req.url);

    // 根据文件的完整路径去读取文件,如果读取到了则返回给用户如果读取不到,则返回404
    fs.readFile(filrname, function (err, data) {
        if (err){
            // res.setHeader('Content-Type', 'text/plain; charset=utf-8');
            // res.end('文件不存在404');
            var filename = path.join(__dirname, 'https', '404.html');
            fs.readFile(filename, function (err,data) {
                res.end(data);
            });
        }else {
            // 通过第三方模块mime,来判断不同的资源对应的Content-Type类型 通过文件后缀计算类型
            res.setHeader('Content-Type', mime.getType(filrname));
            res.end(data);
        }
    })


}).listen(80,function () {
    console.log('服务器启动了,请访问...');
})

request

对应http.IncomingMessage 类
服务器解析用户提交的 http 请求报文,将结果解析到 request 对象中
凡是要获取和用户请求相关的数据都可以通过 request 对象获取
常用对象
    // 获取所有请求报文头headers
    // 返回的是一个对象,这个对象包含了所有的请求报文头
    console.log(req.headers);

    // 获取所有请求报文头rawHeaders
    // 返回的是一个数组,数组中返回的都是请求报文头的字符串
    console.log(req.rawHeaders);

    // 获取请求客户端所使用的http版本httpVersion
    // 1.1
    console.log(req.httpVersion);

    // 获取客户端请求所使用的方法method
    // GET、POST...
    console.log(req.method);

    // 获取请求路径url
    // 不包含主机名称,端口号,协议
    console.log(req.url);

response

对应http.ServerResponse 类
在服务器端用来向用户做出响应的对象。
凡是需要向用户(客户端)响应的操作,都需要通过 response 对象来进行。
常用对象
 	// // 设置响应报文头
    // // response.setHeader(name, value)
    // // 必须放在write和end之前设置,即使不设置响应报文头,系统也会默认设置响应报文头
    // res.setHeader('Content-Type', 'text/html charset=utf-8');
    //
    // // res.statusCode    设置http响应状态码
    // // res.statusMessage 设置http响应状态码对应的消息
    // res.statusCode = 404;
    // res.statusMessage = 'Not found';

    // 写入响应状态码,状态码对应消息,响应报文头
    // response.writeHead(statusCode[, statusMessage][, headers])
    response.writeHead(404, 'Not found', {
            'Content-Length': Buffer.byteLength(body),
            'Content-Type': 'text/plain'
        })

    // 写数据
    // response.write(chunk[, encoding 默认值: 'utf8'][, callback])
    res.write('hello world 你好世界');

    // 每个请求都必须掉用的方法
    // 告诉服务器该响应的报文头,报文体等全部响应完毕,可以考虑本次响应结束
    // response.end([data[, encoding]][, callback])
    // 如果指定了 data,则其效果类似于调用 response.write(data, encoding) 后跟 response.end(callback)
    // 如果指定了 callback,则将在响应流完成时调用
    // res.end() //要响应数据的话必须是String或者Buffer类型
    res.end('over');

常见错误号

EACCES (Permission denied)
    An attempt was made to access a file in a way forbidden by its file access permissions.
    访问被拒绝
EADDRINUSE (Address already in use)
    An attempt to bind a server (net, http, or https) to a local address failed due to another server on the local system already occupying that address.
    地址正在被使用(比如:端口号备占用)
EEXIST (File exists)
    An existing file was the target of an operation that required that the target not exist.
    文件已经存在
EISDIR (Is a directory)
    An operation expected a file, but the given pathname was a directory.
    给定的路径是目录
ENOENT (No such file or directory)
    Commonly raised by fs operations to indicate that a component of the specified pathname does not exist -- no entity (file or directory) could be found by the given path.
	文件 或 目录不存在
ENOTDIR (Not a directory)
    A component of the given pathname existed, but was not a directory as expected. Commonly raised by fs.readdir.
    给定的路径不是目录

npm

查看当前版本 npm -v
更新npm npm install nap@latest -g
使用
	在https://www.npmjs.com/网站中找到需要安装的包
	在项目根目录下执行npm install 包名称 安装
	在nodejs代码中通过requrie(包名),加载模块
创建一个package.json文件 
	一步步生成 npm init
	一次性生成 npm init -y
卸载包 npm uninstall 包名

package.json 文件

package.json 文件的作用?
    1. package.json 文件是一个包说明文件(项目描述文件),用来管理组织一个包(一个项目)
    2. package.json 文件是一个 json 格式的文件
    3. 位于当前项目的根目录下

元数据

package.json 文件中常见的项有哪些?
    name        包的名字
    version     包的版本
    description 包描述
    author		包的作者
    main		包的入口js文件,从main字段这里指定的那个js文件开始执行
    dependencies当前包依赖的其他包
    
如何创建一个 package.json 文件
    1. 通过 npm init 命令 或者 npm init -y 或 npm init -yes 命令
    2. 手动创建一个
注意
    1. 通过 npm init -y 或 npm init -yes 创建 package.json 文件时,执行命令所在的目录接名称中不能包含大写字母
    2. package.json 文件中,项目名称本身不能包含大写字母
    3. npm 更新新版本后,项目所在的文件夹如果包含中文等特殊字符,创建的时候不会提示一步一步的输入,直接报错。

require

1.require() 加载模块时传入的参数是否以 './''../''/' 等等这样的路径方式开头(相对路径或绝对路径都可以)
2.是,那么会按照传入的路径直接去查询对应的模块。
传入的是否为具体的文件名
    require('./test.js') 是具体的文件名
    	直接根据给定的路径去加载模块,找到了加载成功,找不到加载失败
    require('./test'); 不是具体的文件名、
        第一步:根据给定的路径,依次添加文件后缀 .js、.json、.node进行匹配,如果找不到匹配执行第二步
        第二步:查找是否有 test 目录(尝试找 test 包)
            找不到:加载失败
            找到了:依次在 test 目录下查找 package.json 文件(找到该文件后尝试找 main字段中的入口文件)、index.js、index.json、index.node,找不到则加载失败
3. 不是,那么就认为传入的是 "模块名称"(比如:require('http')、require('mime'))
	是核心模块:直接加载核心模块
	不是核心模块:依次递归查找 node_modules 目录中是否有相应的包
        从当前目录开始,依次递归查找所有父目录下的 node_modules 目录中是否包含相应的包
        如果查找完毕磁盘根目录依然没有则加载失败
        打印输入 module.paths 查看

// require('http')
// require('mime')
// 情况一:require() 的参数是一个路径
require('./index2.js')
// index2.js
// index2.json
// index2.node
// index2 文件夹 -> package.json -> main(入口文件 app.js ->
index.js/index.json/index.node) -> 加载失败
require('ndex2')
// 情况二: require() 的参数不是路径,直接就是一个模块名称
// 1. 先在核心模块中查找,是否有和给定的名字一样的模块。如果有,则直接加载该核心模块。
// require('http')
// 2. 如果核心模块中没有该模块那么就会认为这个模块是一个第三方模块(自定义模块)
// 先会去当前js文件所在的目录下去找是否一个一个 node_modules 文件夹
// require('mime')  

require 加载模块注意点
    1. 所有模块第一次加载完毕后都会有 缓存,二次加载直接读取缓存,避免了二次开销,因为有缓存,所以模块中的代码只在第一次加载的时候执行一次
    2. 每次加载模块的时候都优先从缓存中加载,缓存中没有的情况下才会按照 node.js 加载模块的规则去查找
    3. 核心模块在 Node.js 源码编译的时候,都已经编译为二进制执行文件,所以加载速度较快(核心模块加载的优先级仅次于 缓存加载)
    4. 核心模块都保存在 lib 目录下
    5. 试图加载一个和 核心模块 同名的 自定义模块(第三方模块)是不会成功的,自定义模块要么名字不要与核心模块同名,要么使用路径的方式加载
    6. 核心模块 只能通过 模块名称 来加载
    	(错误示例:require('./http'); 这样是无法加载 核心模块http的 )
    7. require() 加载模块使用 ./ 相对路径时,相对路径是相对当前模块,不受执行 node 命令的路径影响
    8. 建议加载文件模块的时候始终添加文件后缀名,不要省略。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值