淘先锋技术网

首页 1 2 3 4 5 6 7

注意:前置知识:回调函数,异步,ajax技术,端口

目录

1.什么是node.js

2.模块的概念

3. 回调函数

4.关于文件的管理

5.关于流的操作

6.关于构建服务器:前端部分,如何向后端发送请求

7.后端创建简单的服务器对象

8.后端如何处理请求

9.前端如何处理返回的数据

10.简易应答和访问的实现代码

11.关于node.js的其他补充


1.什么是node.js

写后端如烹小鲜,而我,不会做饭

一般来说,我们很少用javascript去构建一个后端应用,而是把js划分到经典前端三剑客之一(话说前两天看到一个大哥用js在前端写出了云端图片处理软件........牛蛙牛蛙).把JS解释为机器代码的引擎,其实就是浏览器的底层机制.

而Node.js不是一个编程语言或者框架,而是一个环境,能够脱离浏览器构建一个能让js跑起来的环境.简单来说,就是用js写后端

如果想要区分当前运行环境是浏览器还是node.js,可以了解一下原型prototype,其中浏览器的顶层应该是window,而node.js的底层却是global.

下面不会特别区分nodejs的语法,只会展示一些有关的操作,因为很多其实都是es6的内容这个东西也没有必要特意去学)

其实这篇也近乎解释了为什么vue这类框架需要提前安装node.js

node.js的安装可以直接进入官网Node.js (nodejs.org)

建议选择支持比较多的版本,较为稳定

并且在下载之后要手动配置环境变量,和你们配置java是一样的 

2.模块的概念

模块仍然是es系列标准之一,在这里,每个javascript文件我们都可以将其视为一个模块,或者一个模块的生产者,一个文件可以选择自己想要抛出哪些东西,形成一个其他文件可以require的对象

举个例子

我们有一个名为app2.js的文件,里面要抛出两个东西,变量a和函数counter

把这两个东西以一个对象的形式抛出,就可以在其他的模块中读取到

 在其他的文件中,以对象的形式进行引入,就可以调用这个模块内的属性,函数之类的东西

很类似java中的导包,cpp中的头文件

模块化开发是一个非常重要的思想,后面常用的模块包括文件管理fs,路由管理url,服务器网络管理http协议,都是内置的模块,可以直接使用require语句调用

3. 回调函数

在大多数异步方法中,回调函数可以作为异步处理的一个机制,比如某个函数内置了一个回调函数的参数,就可以设置这个回调函数,来进行异步完成操作以后的行为

关于具体的回调函数的内容,可以详见前面关于异步操作的解释

回调函数是异步操作的一部分,当异步操作完成后会触发回调函数的执行。
在 Node.js 中,回调函数的参数名称并没有限制,通常根据异步操作的结果类型和具体含义来命名参数。一般来说第一个是错误类型,实际由母函数的情况决定

4.关于文件的管理

文件关系的模块为fs,流相关的东西也在这里

var fs=require("fs");

文件的管理分为两种,异步和同步,主要的操作其实也就四个,读入,读出,创建文件夹,删除文件夹

(1)同步操作

同步完成文本文件的读入和读出

用一个变量进行接收,接收的时候要注意编码
var readme=fs.readFileSync("./readme","utf-8");
然后向指定位置写出
fs.writeFileSync("./writeme",readme);

同步完成文件夹的赋值和删除省略

(2)异步操作,区别就在于会异步执行回调函数

所以比如读出的回调函数中,可以启动写入,让逻辑更加清晰

这个回调函数会在执行完流创建以后进行读取

var readme2=fs.readFile("./readme","utf-8",()=>{
    fs.writeFile("./writeme",readme+",and you are finished too!",()=>{
        console.log("you are finished");
    });
});

异步进行文件加创建

fs.mkdir("stuff",()=>{
    console.log("创建成功");
});
fs.rmdir("stuff",()=>{
    console.log("删除成功")
});

5.关于流的操作

流其实和java里面是差不多的东西,也是一种文件处理机制,不过比Java简单太多了

此外,在nodejs构成的服务器端,request和response也具有流的性质

流其实也是eventEmitter的一个实例,所以也具有监听事件的方法on

(对于写入流,有两个事件,data和end,其中data是每一部分文件传入结束时触发的,传入回调函数的参数就是这一部分数据.而end事件是整体的数据传入完成以后才会触发的,data事件会触发多次,但是end事件只会触发一次)

另外注意:当一个可读流(Readable stream)被监听了 data 事件时,数据就开始流动,每当数据块(chunk)被读取时,Readable stream 就会触发 data 事件,将数据块传递给相应的事件处理函数。因此,通过监听 data 事件,我们可以实时获取数据流中的数据。

var readStream=fs.createReadStream("./readme","utf-8");
var writeSeam=fs.createWriteStream("./writeme","utf-8");

readStream.on("data",(data)=>{
    writeSeam.write(data,()=>{
        console.log("一部分数据传递成功");
    });
})
data会多次执行

readStream.on("end",()=>{
    console.log("数据全部传递成功");//这是个异步方法
})
end只会执行一次

解释游戏啊这段代码,这两个流分别根据写入和写出方向构建了两个对象,每次readStream读到了一定数目的数据,就触发data事件,我们根据这个回调函数完成写入流的操作

6.关于构建服务器:前端部分,如何向后端发送请求

发送请求一共是两种:get请求,这种请求主要用来从后端获取大量数据,也可以通过url的方式向后端传递几个简单的参数

这里发送请求的方式是使用ajax技术,可以详见我之前写过的关于ajax的基本使用介绍

[前端基础]关于AJAX的一些梳理_术鸦的博客-CSDN博客

          var xhp=new XMLHttpRequest;
           xhp.open(GET,"http://localhost:3030");
           xhp.onreadystatechange=(()=>{
             ........................
           });
           xhp.send();

post请求:主要用于往后端传入大量数据,区别就在于open函数中的第一个参数改成POST

           var xhp=new XMLHttpRequest;
           xhp.open(method,"http://localhost:3030"); //区别1,这里改成post
           xhp.onreadystatechange=(()=>{
             ..................................
           });
           xhp.send("post发送请求的内容");        //区别2,可以传入数据

7.后端创建简单的服务器对象

服务器有关的东西在模块http中,先引入这个模块,这个模块管理的是http协议下的东西哦,包括构建

var http=require("http");

然后利用http模块中的createServer函数,创建一个服务器,这个函数中内嵌着一个回调函数作为参数使用,这个参数带有两个参数,就是请求体对象req回复体对象res

在这里再谈报文格式显然有点超出格式了,所以我们只说需要干些什么

设置返回状态码,设置返回报文头,以及返回体,这里解释一下为什么前后端可以传递信息,因为在http协议下,传递信息的格式被限制成了"报文"

报文的具体格式可以查阅相关文档

req对象是前端发送过来的,本质上是一个流对象,我们可以直接监听data事件,可以自动开始读取

var http=require("http");
var server=http.createServer((req, res)=>{
    res.statusCode=200;          //设置状态码
    res.setHeader('Access-Control-Allow-Origin', '*');  //设置头
    if(req.method==='POST'){              //根据请求的方式确定如何处理数据
       //传回来的大量数据使用流的方式进行处理
       req.on("data",(data)=>{
           console.log(data);
       });
        req.on("end",()=>{
            console.log("已经完成请求了");
        });
       res.end("来自后端,经过POST请求的数据");
    }else{
       res.end("来自后端,经过GET请求的大量数据");

    }
})

最后监听端口,

端口就相当于这个服务器对象对外开放的窗口,前端需要从端口访问这个进程,才能有结果

server.listen("3030","127.0.0.1",()=>{
    console.log("服务器开始监视3030端口")
});

8.后端如何处理请求

(1)如果是post请求,我们主要需要把req中带来的数据给读取即可

建议使用流的方式读取,刻度流

req.on("data",(data)=>{
           console.log(data);
       });
        req.on("end",()=>{
            console.log("已经完成请求了");
        });

(2)如果是get请求,我们需要往前端传入数据

按照目前来说,使用end函数进行返回,是最简单的方式

res.end("来自后端,经过GET请求的大量数据");

9.前端如何处理返回的数据

前端处理返回数据的方式目前只学习了简单数据,太大的数据需要改变为流对象

这个后面有缘再说吧QWQ

xmlhttprequest对象中,有一个response对象,这个东西就算返回的数据

读取示例
console.log(xhp.response);

10.简易应答和访问的实现代码

var http=require("http");
var server=http.createServer((req, res)=>{
    res.statusCode=200;          //设置状态码
    res.setHeader('Access-Control-Allow-Origin', '*');  //设置头
    if(req.method==='POST'){              //根据请求的方式确定如何处理数据
       res.end("来自后端,经过POST请求的数据");
    }else{
       res.end("来自后端,经过GET请求的大量数据");
    }
})

server.listen("3030","127.0.0.1",()=>{
    console.log("服务器开始监视3030端口")
});

前端代码如下

function detchData(method){
           var xhp=new XMLHttpRequest;
           xhp.open(method,"http://localhost:3030");
           xhp.onreadystatechange=(()=>{
               if(xhp.readyState===4 && xhp.status===200){
                   //这里根据不同的情况返回不同的数值
                   console.log(xhp.response);
               }
           });
           xhp.send("post发送请求的内容");
       }

11.关于node.js的其他补充

(1)NPM包管理机制

npm可以理解为一个开源的社区?其实是nodejs的模块包管理,通过npm的方式可以获得别人弄好的轮子(比如常用的express.js,可以大大简化操作)
或者可以理解为一个共享机制?可以用来下载别人的包
npm是node.js自带的一个命令

(2)介绍另一个启动方式

nodemon,一个工具,检测文件改变,然后会重启后端
使用npm的方式进行安装
启动项目的方式也从node变成了nodemon
这个东西也可以到时候写到脚本里面
 

(3)package.json

这个东西可以说是老朋友了,就目前我们接触到的来说,有两种用法

1.记录着我们在项目中的依赖,启用指令

npm install

就可以读取记录信息,可以把用到的模块重新下载

这种是方便接收其他人的项目

2.这个文件中内置着某些启动脚本,idea启动也是根据这个json文件中的脚本来进行的

比如我们想要改成nodemon方式启动项目,就可以在这个文件里修改