• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
兽籽Giselle
博客园    首页    新随笔    联系   管理     
Nodejs笔记

nodejs基础知识

nodejs和js的异同

相同点 javascript和nodejs
以ECMAScript为基础 数据结构的定义,语法、内置对象和方法等都相同。

不同点 javascript nodejs
顶层对象 window global
操作对象 操作浏览器,属前端范畴。包括↓
DOM: 操作页面元素的方法;
BOM: 操作浏览器元素的方法。
操作系统/网络等,更偏向于后端。包括↓
OS: 操作操作系统的方法;
file: 操作文件系统的方法;
net: 操作网页的方法;
database: 操作数据库的方法;
net: 操作网页的方法。
模块概念 无 有

nodejs的使用

nodejs软件是无界面形式的,打开后类似于命令行,且可以直接在命令行里打开nodejs文件。

操作命令行

  • windows下,通过win+r可以直接打开运行,输入cmd,打开命令行界面
  • 直接敲 node +回车,若得到 >和闪动的光标,表示node安装正确
  • 按2次 ctrl+c可结束执行进程
  • win7在命令行里输入CLS可清屏
  • 命令行里输入node+空格+要运行的程序
  • 命令行内不区分大小写
  • cd\回到根目录,cd..回到上级目录
  • \后面输入路径, >后面输入命令

nodejs中的模块

  • 在node中,文件和模块是一一对应的,一个文件就是一个模块
  • 每个模块都有自己的作用域
  • 通过var申明的并不是全局变量,而是该模块作用域下的变量
  • node中要通过 global.变量名 的方式申明全局变量,前面不用加var
  • node中,像全局变量,实际上是当前模块下的变量有:

__filename → 当前文件被解析后的绝对路径,是属性,末尾无括号

模块加载机制

在js中通过<script>标签引入其他js文件,但在node中没有标签的概念,它是用模块加载机制来引入其他文件。即:
require方法 → require('模块地址'); → 使用时要注意两个问题:

  • 一是路径问题:

  1. 地址之间用/,而不是
  2. 既可以写绝对地址,也可以写相对地址
  3. 写相对地址时,若是同一文件夹下的文件,不能省略./
  4. 一旦直接写文件名,会加载node中的核心模块,也就是node_modules中的模块

  • 二是文件查找问题:

查找顺序:文件名→文件名.js→文件名.json→文件名.node→还找不到,报错

module和exports

在node中用var定义的变量是当前模块下的变量,无法直接和外部模块共享,解决办法:

  1. 用global将变量定义为全局变量;→不推荐这样做
  2. 利用每个模块内置的module对象;
  3. 利用每个模块内置的exports对象;

module对象

module对象保存和提供了与当前模块有关的一些信息,比如,id是当前模块的唯一标识;filename是当前模块的文件名称;children是当前模块加载的其他模块的信息。
module对象中有一个子对象,即exports属性,可以将当前模块中的变量暴露出去;使用方法:module.exports.属性名=变量名;例:

var a=20;
module.exports.a=a;

require方法返回的就是被调用模块的module.exports属性;

exports对象

每个模块中内置的exports对象===该模块下的module.exports属性
一旦改写(不是添加)exports或module.exports,他们就没有指向关系了,所以尽量只是添加,不要改变他们的指向关系

process对象

process是全局对象

stdin/stdout: 标准输入输出流(IO)

stdin和stdout提供了操作输入和输出数据的方法,通常也被称为IO操作

Buffer类

Buffer类用于操作二进制数据流
当为buffer对象分配空间大小后,长度是固定的,不能更改
可以修改长度内的数据,但不能添加数据
length指的是字节长度,不是字符串的长度

  • new Buffer(size);创建一个buffer对象并为这个对象分配一个大小,size为数据类型
var bf = new Buffer(5);
console.log(bf);//<Buffer 88 f3 30 00 02>→打印出来的是16进制数据,数据随机
bf[6]=8;
console.log(bf);//<Buffer 88 f3 30 00 02>→没有出现第6位数
bf[0]="8";
console.log(bf);//<Buffer 08 f3 30 00 02>→第一个数被改写
  • new Buffer(array);创建一个buffer数组
var bf = new Buffer(["ab","2",4]);
console.log(bf);//<Buffer 00 02 04>
bf[6]=8;
console.log(bf);//<Buffer 00 02 04>→同样不能添加数据
bf[0]="8";
console.log(bf);//<Buffer 08 02 04>→同样可以改写数据
  • new Buffer(string,[encoding]);创建一个buffer对象
var bf = new Buffer("hua","utf-8");
console.log(bf);//<Buffer 68 75 61>→16进制
for (var i=0; i<bf.length;i++){
    console.log(bf[i]);//打印出来的是2进制
    console.log(String.fromCharCode(bf[i]));//将编码转换成字符串
}
// 104
// h
// 117
// u
// 97
// a

buffer.write()方法

buffer对象.write(要写入到buffer对象的字符串[,从buffer对象的第几位开始写入][,写入的字符串长度],[写入的字符串的编码]);

buffer.slice()和buffer.copy()方法

相同点:都是截取一个buffer对象,获得一个新的buffer对象
不同点:使用slice,改变新buffer的数据会同时改变原buffer数据;copy就不会

var str="caihua";
var bf=new Buffer(str);
console.log(bf);//<Buffer 63 61 69 68 75 61>
var bf1=new Buffer(5);
console.log(bf1);//<Buffer 00 00 00 00 38>
var bf2=bf.copy(bf1,1,2,3);
console.log(bf1);//<Buffer 00 69 00 00 38>
console.log(bf2);//1,返回的是写入到新bf1的长度

File System文件系统模块

该模块是核心模块,需要使用require方法导入fs模块后使用
该模块提供了操作文件的一些API

fs.open(path,flags,[mode],callback)

path:要打开的文件路径
flags:打开文件的方式,读/写
mode:设置文件的模式,读/写/执行,对应4/2/1
callback:回调函数
  err:文件打开失败的错误提示保存在err里,打开成功err为null
  fd:被打开文件的标识

举个栗子

var projectData={
    "name":"caihua",
    "fileData":[
        {
            "name":"css",
            "type":"dir"
        },{
            "name":"js",
            "type":"dir"
        },{
            "name":"index.html",
            "type":"file",
            "content":"<html>\n\t<head>\n\t\t<title>title</title>\n\t</head>\n\t<body>\n\t\t<h1>caihua is nice</h1>\n\t</body>\n</html>"
            //\n是折行,\t是缩进
        }
    ]
};
var fs=require("fs");
if(projectData.name){
    fs.mkdirSync(projectData.name);
    var fileData=projectData.fileData;
    if(fileData && fileData.forEach){//如果fileData存在,并且它是数组,有forEach方法
        fileData.forEach(function(f){//f是数组fileData里的每一个对象
            f.path=projectData.name+"/"+f.name;//构建一个完整的目录
            f.content=f.content||"";//避免没有content时出错
            switch(f.type){
                case "dir":
                    fs.mkdirSync(f.path);
                    break;
                case "file":
                    fs.writeFileSync(f.path,f.content);
                    break;
                default:
                    break;
            }
        })
    }

合并文件,举个栗了

var fs=require("fs");
var filedir="./test";//要合并内容的文件夹
fs.watch(filedir,function(ev,file){//监听要合并内容的文件夹里的内容
    fs.readdir(filedir,function(err,datalist){//读取该文件夹下的内容
        //datalist是一个数组,用来装该文件夹下的文件名
        var arr=[];//用来装要合并内容的文件的路径
        datalist.forEach(function(f){
            if(f){
                var info=fs.statSync(filedir+"/"+f);//参数是路径
                if(info.mode==33206){
                    arr.push(filedir+"/"+f);
                }
            }
        });
        var content="";//用来装该文件夹下每个文件的内容
        arr.forEach(function(f){
            var c=fs.readFileSync(f);
            content+=c.toString()+"\n";
        });
        fs.writeFile("./index.js",content);
    })
});

用到的方法:

  1. fs.watch(文件夹所在路径,回调函数)→监听文件夹内的变化
  2. fs.readdir(文件夹所在路径,回调函数)→读取文件夹下所有文件
  3. fs.statSync(文件所在路径)→读取文件详情
  4. fs.readFileSync(文件所在路径)→读取文件内容,得到的是buffer对象,二进制,可以用toString方法转成字符串,\n是换行
  5. fs.writeFile(要写入内容的文件的路径,要写入的内容)→写入内容

使用node进行web开发

  1. 用户通过浏览器发送http请求到指定的主机(服务器)
  2. 服务器接收请求,处理请求
  3. 服务器处理完成,返回对应的数据到用户机器(浏览器)
  4. 浏览器接收数据并进行分析和处理

浏览器即客户端,服务器就是服务端,请求过程就是两台机器之间的数据通信,即两台机器的交互过程
要进行web开发,必须搭建一个服务器来接收来自任何客户端的链接和请求,并进行对应的处理
nodejs中可以通过http模块来搭建服务器(非nodejs的核心模块)

http模块

用到的方法

  1. http.createServer(回调函数);→创建并返回一个web服务器对象。
  2. server.listen(port,[hostname,][backlog,][callback])→listen方法可以用来设定监听哪个网卡的哪个端口的数据。
  3. server.address();→{ address: '::', family: 'IPv6', port: 9960 }→获取服务器地址,address不设置,默认监听所有网卡过来的数据;端口可以由node自动分配,每刷新一次,端口会变,所以建议手动设置端口。端口不能随意设置,1-1024之间的端口号已经被约定给系统或应用程序等使用(ipachy监听的端口号是80,ftp监听的端口号是21),所以建议将端口设置大一点。
  4. server.on("error",function(err){});→该方法是为了预防端口设置错误,当端口设置错误时触发。
  5. server.on("listening",function(){});→当端口设置正确时触发。
  6. server.on("request",function(){});→当向该地址的该端口发送请求时触发。
    7.http.STATUS_CODES;→是一个对象,全部的标准http响应状态码的集合和简短描述。

端口的概念

网卡是一个数据交互的大通道,如果没有端口,任意程序可以监听网卡上的任意数据,会造成混乱,于是诞生了端口。网络数据交互的程序只能监听从对应端口进入的数据,一个应用程序可以监听多个端口的数据,一个端口的数据只能被一个应用程序监听。

request请求

  1. server.on("request",function(){})的request事件其实就是http.createServer(回调函数)里的回调函数,函数有两个参数request和response。request提供了一个客户端信息对象,会存储和客户端发送的请求有关的信息;response则提供了一个服务端信息对象,比如用来处理服务端向客户端发送的数据。
  2. request和response都是http对象的实例

request对象包含的重点内容

  • httpVersion:使用的http版本信息,一般为1.1
  • headers:请求头信息中的数据
  • url:请求的地址
  • method:请求方式

response对象包含的重点内容

  • write(chunk,[encoding]):发送一个数据块到响应正文中。
  • end([chunk,][encoding]):当所有的正文和头信息发送完了后调用该方法告诉服务器,数据已发送完成。这个方法在每次发送完信息后必须调用,且是在最后调用。
  • statusCode:该属性用来设置返回的状态码
  • setHeader(name,value):设置返回头信息
  • writeHead(statusCode,[reasonPhrase],[headers]):这个方法只能在当前请求中使用一次

用户发送http请求→服务器响应并处理数据→返回给客户端→客户端接收数据并进行处理

url模块

url.parse(路径名);→将url解析成一个对象,方便调用

举个栗子

var http=require("http");
var url=require("url");
var server=http.createServer();
server.listen(8080,"localhost");
server.on("request",function(req,res){
    var urlStr=url.parse(req.url);
    switch (urlStr.pathname){
        case "/":
            //首页
            res.writeHead(200,{
                "content-type":"text/html;charset=utf-8"
            });
            res.end("<h1>这是首页</h1>");
            break;
        case "/users":
            //用户页面
            res.writeHead(200,{
                "content-type":"text/html;charset=utf-8"
            });
            res.end("<h1>这是用户页面</h1>");
            break;
        default:
            res.writeHead(404,{
                "content-type":"text/html;charset=utf-8"
            });
            res.end("<h1>这是错误页面</h1>");
            break;
    }
});

使用fs模块实现行为表现分离

用到的方法和属性

  1. __dirname是全局变量。在任何模块文件内部,可以使用__dirname变量获取当前模块文件所在目录的完整绝对路径。
  2. fs.readFile(file,function(err,data){});→读取文件内容
posted on 2017-03-22 17:26  兽籽Giselle  阅读(196)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3