目录

一.流和管道

二.Web服务器输出内容

1.server输出文本信息

2.server输出一个HTML文件(效果)

3.server输出JSON格式的数据

三.模块化组织代码

四.路由


一.流和管道


流的概念并不难理解,例如:我们平时前后端交互其实就是转换成流来进⾏交互的,我们之前也讲过⽂件的读写,⽂件的读写也属于流的操作的体现。这是如果⽂件特别⼤的时候,我们还是要采取buffer处理。


我们现在命令⾏中操作⼀个基础操作


ls



ls | grep app




ls | grep app 这个命令在 linux 或 mac 才适合,或者 windows 的 git bash 也可以的。



如果是 windows 的命令提示符,对应的查找⽂件的命令应该是: dir | findstr app



下⾯我们看⼀下流的具体操作




使用流读取文件:




//导入文件流模块
var fs=require('fs');

//__dirname是获取当前对象
var myReadstream =fs.createReadStream(__dirname+'/readMe.txt');
//编码格式也可以直接设置在上面函数的第二个参数那里
//不设置utf-8编码的话,此对象返回的就是buffer对象,即下面的chunk是buffer对象,数据量大时会有多个buffer
myReadstream.setEncoding('utf-8');

var data="";
//为流对象设置监听器
myReadstream.on('data',function(chunk){
    
    //console.log(chunk);
    //使用data而不直接输出chunk为了还没读取完就进行了其他操作
    data+=chunk;
    //可能还没读取完就开始执行下面的操作
})

myReadstream.on('end',function(){
    console.log(data);
})



上述代码读到的是 buffer 对象,这也是他性能提升的主要原因。如果⽂件过⼤,会处理成多个 buffer 对象。




使用流写入文件:



var fs=require("fs");

var myReadStream=fs.createReadStream(__dirname+"/readMe.txt","utf-8");

var myWriteStream=fs.createWriteStream(__dirname+"/writeMe.txt");

var data=""
//data事件和end事件不是自己随便起的名,而是已经规定好的的事件
//每当流将数据块的所有权移交给消费者时,则会触发 'data' 事件。
//下面两个事件可在api文档的流部分找到
myReadStream.on('data',function(chunk){
    myWriteStream.write(chunk);
});

//读取结束之后,输出提示
//当流中没有更多数据可供消费时,则会触发 'end' 事件。
myReadStream.on("end",function(){
    console.log("读取完成");
})


不从文件读取,而自己设置要写入的内容:

var fs=require("fs");
var myWriteStream=fs.createWriteStream(__dirname+"/writeMe.txt");
//要写入的数据
var myData="Hello Node";
//写入要写的数据
myWriteStream.write(myData);
//调用Writable. end()方法表示不再有数据写入Writable。
myWriteStream.end();
myWriteStream.on("finish",function(){
    console.log("写入完成");
})

利用管道实现输入输出(代码较为简洁):

var fs=require('fs');

var myReadStream=fs.createReadStream(__dirname+'/readMe.txt');
var myWriteStream=fs.createWriteStream(__dirname+'/writeMe.txt');

//将read中的内容写入write中
myReadStream.pipe(myWriteStream);

二.Web服务器输出内容

1.server输出文本信息

var http=require("http");

//创建服务器对象
var server=http.createServer(function(req,res){
    console.log("request");
    res.writeHead(200,{
        //传输纯文本
        "Content-Type":"text/plain"
    })
    res.end("hello from server!");
})
//node的默认端口是3000,服务器地址这里设置为127.0.0.1
server.listen(3000,"127.0.0.1");
console.log("服务器运行在3000端口上");

先在终端运行此脚本文件,再在浏览器地址栏上输入http://localhost:3000/

即可看到服务器返回的信息 hello from server!

nodeport端口设置_Nodejs

 此时终端一直处于运行状态,按Ctrl+C终止运行。

服务器运行在3000端口上
request
request

2.server输出一个HTML文件(效果)

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    Hello world!
</body>
</html>

index.js:

var http=require("http");
var fs=require("fs");

//创建服务器对象
var server=http.createServer(function(req,res){
    console.log("request");
    res.writeHead(200,{
        //可以传输纯文本,HTML,JSON
        "Content-Type":"text/html"
    })
    //读取html文件
    var myReadStream=fs.createReadStream(__dirname+"/index.html","utf-8");
    //res.end("hello from server!");
    //将read读取的嫩容通过管道输入到response中
    myReadStream.pipe(res);
})
//node的默认端口是3000,服务器地址这里设置为127.0.0.1
server.listen(3000,"127.0.0.1");
console.log("服务器运行在3000端口上");

输出:

浏览器:浏览器显示的不是html的源代码,而是效果图。

nodeport端口设置_JavaScript_02

终端:

服务器运行在3000端口上
request
request

3.server输出JSON格式的数据

当然,个别时候,我们可能需要接受⼀个服务器返回的⻚⾯,例如,⽀付相关的返回⼀般都是返回⼀个⻚⾯直接渲染。

var http=require("http");
var fs=require("fs");

//创建服务器对象
var server=http.createServer(function(req,res){
    console.log("request");
    res.writeHead(200,{
        //可以传输纯文本,HTML,JSON
        "Content-Type":"application/json"
    })
    var obj={
        name:"kd",
        age:20
    }
    //将json数据转换为字符串
    res.end(JSON.stringify(obj));
})
//node的默认端口是3000,服务器地址这里设置为127.0.0.1
server.listen(3000,"127.0.0.1");
console.log("服务器运行在3000端口上");

输出:

终端:

服务器运行在3000端口上
request
request

 浏览器:

nodeport端口设置_JavaScript_03

三.模块化组织代码

将程序中的各个模块拆分开来, 降低耦合度。以上面的例子,进行拆分。

server.js:

服务器启动功能实现,封装到一个函数中。

var http=require("http");
var fs=require("fs");
var data=require("./data.json");

//启动服务器函数
function startServer(){
    //创建服务器对象
var server=http.createServer(function(req,res){
    console.log("request");
    res.writeHead(200,{
        //可以传输纯文本,HTML,JSON
        "Content-Type":"application/json"
    })
    //读取html文件
    //var myReadStream=fs.createReadStream(__dirname+"/index.html","utf-8");
    //res.end("hello from server!");
    //将read读取的嫩容通过管道输入到response中
    //myReadStream.pipe(res);
    
    //将json数据转换为字符串
    res.end(JSON.stringify(data));
})
//node的默认端口是3000,服务器地址这里设置为127.0.0.1
server.listen(3000,"127.0.0.1");
console.log("服务器运行在3000端口上");
}

//导出函数
module.exports={
    startServer
}

index.js:

主入口程序:

/*主入口文件 */

const server=require("./server.js");

//启动服务器
server.startServer();

data.json:

json数据文件:

{
    "name":"kd",
    "age":20,
    "sex":"male"
}

输出:

浏览器:

nodeport端口设置_nodeport端口设置_04

终端:

服务器运行在3000端口上
request

四.路由


在实际的开发场景中,我们需要根据 不同的地址 返回不同的数据,也就是我们⽇常所说的路由效果


在上⼀⼩节中,如果我们直接访问 http://localhost:3000/home 和之前的访问是没有区别的,也就是我们⽆法根据不同地址返回不同的数据,接下来我们处理⼀下,形成路由



404.html:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    404页面!
</body>
</html>

home.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    Home!
</body>
</html>

data.json:

{
    "name":"kd",
    "age":20,
    "sex":"male"
}

server.js:

  1. 其他
var http = require("http");
var fs = require("fs");
var data = require("./data.json");

//启动服务器函数
function startServer() {
    //创建服务器对象
    var server = http.createServer(function (req, res) {
        //req.url是主机名:端口号后面那一部分
        console.log(req.url);
        /*
        ==用于一般比较,===用于严格比较,==在比较的时候可以转换数据类型,
        ===严格比较,只要类型不匹配就返回flase。
        */
        if (req.url === "/" || req.url === "/home") {
            //向请求发送响应头。状态码是一个3位的HTTP状态码,比如404。
            //最后一个参数header是响应头。
            //也可以提供一个人类可读的statusMessage作为第二个参数。
            res.writeHead(200, { "Content-Type": "text/html" });
            //管道从左往右输出,把从指定路径文件中读取的内容输出到response中
            fs.createReadStream(__dirname + "/home.html", "utf-8").pipe(res);

        } else if (req.url === "/api/user") {
            res.writeHead(200, {
                //传输JSON
                "Content-Type": "application/json"
            })
            //可选的chunk和encoding参数允许在关闭流之前立即写入最后一个额外的数据块。
            res.end(JSON.stringify(data));

        } else {
            res.writeHead(404, {
                "Content-Type": "text/html"
            })
            fs.createReadStream(__dirname + "/404.html", "utf-8").pipe(res);
        }
    })//server

    //node的默认端口是3000,服务器地址这里设置为127.0.0.1
    server.listen(3000, "127.0.0.1");
    console.log("服务器运行在3000端口上");

}

//导出函数
module.exports = {
    startServer
}

index.js:

/*主入口文件 */

const server=require("./server.js");

//启动服务器
server.startServer();