Node.js之Web学习笔记
Posted 二木成林
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js之Web学习笔记相关的知识,希望对你有一定的参考价值。
http模块
入门
Node.js提供了系统模块http用来写服务端代码。http
模块是系统核心模块,不需要下载只需要直接引入即可,引入代码如下:
var htttp = require('http');
创建简单的服务端代码如下:
// 第一步,引入http模块
var http = require("http");
// 第二步,通过http模块的createServer方法创建一个server
var server = http.createServer();
// 第三步,监听"request"事件,获取请求,发送响应
server.on("request", function (request, response) {
console.log("接收到客服端请求,请求路径是:" + request.url);
});
// 第四步,设置监听端口,启动服务器
server.listen(8888, function () {
console.log("服务器启动成功,可以通过 http://127.0.0.1:8888 来进行访问");
});
注意:
request
是请求处理函数,会接收两个参数:Request请求对象和Response响应对象。请求对象Request可以获取客服端的一些请求信息,如请求路径;响应对象Response可以来给客服端发送响应消息。listen()
函数中的端口号可以任意设置。- 每次修改代码后要重启。
在浏览器输入http://localhost:8888/hello
访问就可以在控制台看到打印结果:
响应数据给客户端
如果我们要响应一些数据给客服端,可以通过响应对象Response来输出一些信息。
response.write(data);
:向客户端输出数据,可以多次调用该方法。response.end();
:结束输出。
// 第一步,引入http模块
var http = require("http");
// 第二步,通过http模块的createServer方法创建一个server
var server = http.createServer();
// 第三步,监听"request"事件,获取请求,发送响应
server.on("request", function (request, response) {
console.log("接收到客服端请求,请求路径是:" + request.url);
// 通过Response对象的write()方法可以向客户端输出数据
response.write("hello world!\\n");
response.write("hello node.js!");
// 最后还要通过end()方法来结束输出,否则会一直等待
response.end();
});
// 第四步,设置监听端口,启动服务器
server.listen(8888, function () {
console.log("服务器启动成功,可以通过 http://127.0.0.1:8888 来进行访问");
});
在浏览器查看如下:
其实可以直接通过response.end(data);
方法向客户端输出数据。
server.on("request", function (request, response) {
console.log("接收到客服端请求,请求路径是:" + request.url);
// 通过Response对象的end(data)方法可以向客户端输出数据
response.end("hello world!")
});
根据不同请求路径返回不同数据
现在写的代码功能非常小,无论什么请求,响应的结果都是"hello world!"
,我们需要根据不同的请求路径来响应不同的结果,如/index
响应首页、/login
响应登录、/register
响应注册等。可以通过if判断url来进行不同的响应:
// 第一步,引入http模块
var http = require("http");
// 第二步,通过http模块的createServer方法创建一个server
var server = http.createServer();
// 第三步,监听"request"事件,获取请求,发送响应
/*
根据不同的请求路径发送不同的响应结果:
1.获取请求路径
通过request.url属性获取到请求的路径,即端口之后的那一部分路径,如"http://127.0.0.1:8888"默认是"/","http://127.0.0.1:8888/hello"是"/hello"
2.根据if判断来根据路径进行不同的响应返回
*/
server.on("request", function (request, response) {
// 获取url属性,然后if判断
var url = request.url;
if (url === '/') {
response.end('index page');
} else if (url === '/hello') {
response.end('hello world!');
} else if (url === '/login') {
response.end('login page');
} else {
response.end('404 Not Found.');
}
});
// 第四步,设置监听端口,启动服务器
server.listen(8888, function () {
console.log("服务器启动成功,可以通过 http://127.0.0.1:8888 来进行访问");
});
响应中文数据
当我们直接响应返回中文数据的时候,浏览器页面会中文乱码显示。因为node.js响应回的数据编码格式是UTF-8,而中文系统的浏览器页面解析用的是GBK。通过设置Content-Type响应头来设置响应数据内容的编码格式:
// 第一步,引入http模块
var http = require("http");
// 第二步,通过http模块的createServer方法创建一个server
var server = http.createServer();
// 第三步,监听"request"事件,获取请求,发送响应
server.on("request", function (request, response) {
// 通过响应对象Response的setHeader(name, value)方法设置响应头,来设定响应数据内容是什么类型的
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
response.end('hello 世界!');
});
// 第四步,设置监听端口,启动服务器
server.listen(8888, function () {
console.log("服务器启动成功,可以通过 http://127.0.0.1:8888 来进行访问");
});
Content-Type
还可以设置其他响应内容格式:
// 第一步,引入http模块
var http = require("http");
var fs = require("fs");
// 第二步,通过http模块的createServer方法创建一个server
var server = http.createServer();
// 第三步,监听"request"事件,获取请求,发送响应
server.on("request", function (request, response) {
// 通过响应对象Response的setHeader(name, value)方法设置响应头,来设定响应数据内容是什么类型的
var url = request.url;
if (url === '/plain') {// 普通文本
// text/plain是普通文本类型
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
response.end('hello 世界!');
} else if (url === '/html') {// 直接输出html内容
// text/html是html格式的字符串
response.setHeader('Content-Type', 'text/html; charset=utf-8');
response.end("<p>hello node.js.<a href='#'>点我</a></p>")
} else if (url === '/html-from-file') {// 从.html文件中读取内容
fs.readFile('hello.html', function (err, data) {
if (!err) {
// text/html是html格式的字符串,通常读取.html文件中的内容
response.setHeader('Content-Type', "text/html; charset=utf-8");
response.end(data);
} else {
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
response.end('hello.html文件读取失败,请稍后重试!');
}
});
} else if (url === '/star.jpg') {
fs.readFile('star.jpg', function (err, data) {// 图片
if (!err) {
// data默认是二进制数据,可以通过data.toString()方法转换成能识别的字符串
// response.end(chunk)方法中的参数支持两种数据类型:二进制和字符串
// 图片就不需要指定编码了,通常只有字符串才需要指定编码
response.setHeader('Content-Type', "image/jpeg");
response.end(data);
} else {
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
response.end('hello.html文件读取失败,请稍后重试!');
}
});
}
});
// 第四步,设置监听端口,启动服务器
server.listen(8888, function () {
console.log("服务器启动成功,可以通过 http://127.0.0.1:8888 来进行访问");
});
代码风格
关于javascript代码规范,比较规范的有:
而关于JavaScript中分号是否添加的问题:
;`hello`.toString()
/*
当采用了无分号的代码风格时,只需要注意下面几个情况:
当一行代码是以(或[或`开头的时候,则在前面补一个分号就能避免一些语法解析错误。
所以会发现一些第三方代码中以;开头。
所以无论代码是否有分号,都建议如果一行代码是以(或[或`开头的,则最好都在前面补上
一个分号,有些人也会使用!或~符号,都是同样的效果。
*/
模板引擎art-template
概述
可以用来服务端渲染数据,然后直接传到客户端使用。
官方教程:art-template
推荐博客:模板引擎 – art-template
基本使用
我们可以通过响应对象Response的write或end方法向客户端输出文本数据,也可以输出html格式的字符串,更可以读取.html
文件向客户端输出数据。如果我们向客户端输出大量数据,那么可能需要拼接html格式的字符串来显示不同的内容,例如:
// 导入http模块
var http = require("http");
// 创建服务器
var server = http.createServer();
// 监听request事件
server.on("request", function (request, response) {
var name = "张三";
var age = 18;
var hobbies = ["听歌", "阅读", "打游戏"];
// 拼接字符串
var html = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello</title>
</head>
<body>
<p>大家好,我的名字是:` + name + `</p>
<p>我今年` + age + `岁了</p>
<p>我的爱好有:` + hobbies[0] + `;` + hobbies[1] + `;` + hobbies[2] +
`</p>
</body>
</html>
`;
response.end(html);
});
// 服务器监听端口,启动服务器
server.listen(8888, function () {
console.log("服务器启动了!可以通过 http://127.0.0.1:8888 进行访问!")
});
但我们发现拼接字符串非常麻烦,如果html代码很多,那么就更麻烦了。所以可以使用模板引擎,在html文件中的一些关键信息用一些符号进行标记,然后统一进行替换。而art-template就是这样的一个模板引擎。使用的步骤如下:
// 第一步,安装art-template模块
npm install art-template
// 第二步,在js文件中引入该模块
var template = require('art-template');
// 第三步,使用参考API
template.render('模板字符串', 替换对象);
所以我们先在当前项目下安装art-template
模块。
然后创建一个html文件,在里面使用模板引擎的{{ }}
语法。其中{{ }}
里面的变量名任意取,但遍历需要遵循模板引擎的语法格式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Index</title>
</head>
<body>
<p>大家好,我的名字是:{{ name }}</p>
<p>我今年{{ age }}岁了</p>
<p>我的爱好有:{{ each hobbies}} {{ $value }} {{ /each }}</p>
</body>
</html>
然后在js里通过读取.html
文件的方式向客户端输出数据,并使用模板引擎渲染数据。
// 导入http模块
var http = require("http");
// 导入art-template模块
var template = require("art-template");
// 导入fs模块
var fs = require("fs");
// 创建服务器
var server = http.createServer();
// 监听request事件
server.on("request", function (request, response) {
fs.readFile("./index.html", function (err, data) {
if (!err) {
// 默认读取到的data是二进制数据,模板引擎的render方法需要接收的是字符串,所以要将data转换成字符串才能给模板引擎使用
var ret = template.render(data.toString(), {
name: '张三',
age: 19,
hobbies: ['阅读', '听歌', '打游戏']
});
response.end(ret);
}
});
});
// 服务器监听端口,启动服务器
server.listen(8888, function () {
console.log("服务器启动了!可以通过 http://127.0.0.1:8888 进行访问!")
});
注意:
template.render()
方法在这里传入了两个参数,第一个参数就是写了模板语法的html字符串,不过这里传入的是从文件读取的html字符串;第二个参数是数据对象,里面定义了传给模板引擎的值,其中键名就是{{ }}
里面的变量名,键值就是要赋予的具体值。template.render()
方法的返回值就是渲染数据成功返回的字符串,可以直接输出到客户端了。
在浏览器访问结果如下:
实例:文件浏览器
需求
需求:通过http
模块和art-template
模板引擎来实现文件浏览器的效果,如下图:
涉及知识
涉及模块:
- http
- fs
- path
其他技术:
- art-template模板引擎
实现原理:根据请求的路径使用fs模块直接读取系统中的文件目录及其相关属性,然后使用模板引擎art-template渲染出来。
代码实现(Windows系统)
在Windows系统下的代码和Linux系统下的路径有所区别:
app.js
var http = require('http');
var template = require('art-template');
var fs = require('fs');
var path = require('path');
var server = http.createServer();
server.on('request', function (request, response) {
var url = request.url;
if (url === '/') {
fs.readFile('./index.html', function (err, data) {
if (!err) {
var files = [
{isDir: true, name: "C:/", path: "C:/"},
{isDir: true, name: "D:/", path: "D:/"},
{isDir: true, name: "E:/", path: "E:/"},
{isDir: true, name: "F:/", path: "F:/"},
{isDir: true, name: "G:/", path: "G:/"}];
var ret = template.render(data.toString(), {files: files});
response.end(ret);
}
});
} else if (url.startsWith('/C:') || url.startsWith('/D:') || url.startsWith('/E:') || url.startsWith('/F:') || url.startsWith('/G:')) {
url = decodeURIComponent(url.substring(1));// 中文是进行URL编码的,所以需要对路径进行解码
// 根据目录路径读取该目录下的所有文件名称
fs.readdir(url, function (err, files) {
fs.readFile('./index.html', function (err, data) {
if (!err) {
var paths = [];
for (var i in files) {
var item = new Object();
// 文件名
item.name = files[i];
// 文件绝对路径
var p = path.join(url, files[i]);
item.path = p;
if (files[i].startsWith('System Volume Information')) {
item.isDir = true;
} else if (files[i].startsWith(以上是关于Node.js之Web学习笔记的主要内容,如果未能解决你的问题,请参考以下文章