目录
一.流和管道
二.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!
此时终端一直处于运行状态,按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的源代码,而是效果图。
终端:
服务器运行在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
浏览器:
三.模块化组织代码
将程序中的各个模块拆分开来, 降低耦合度。以上面的例子,进行拆分。
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"
}
输出:
浏览器:
终端:
服务器运行在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:
- 其他
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();