目录
1.1 初识http模块
http模块是Nodejs官方提供的,用来创建 web 服务器的模块。通过http模块提供的http.createServer(),就能方便的把一台普通的电脑变成一台web服务器,从而对外tigweb资源服务
1.2 如何创建基本的 web 服务器
- 导入HTTP模块
- 创建服务器实例对象( http.createServer)
- 绑定请求事件(server.on('request',(req,res)=>{}))
- 监听指定端口请求(.listen()启动)
//1.导入 http 模块
const http = require('http');
// 2.创建服务器实例对象
const server = http.createServer();
//3.为服务器绑定 request 事件,监听客户端的请求
server.on('request',(req,res) => {
console.log('Someone visit our web server.');
});
//4.启动服务器
server.listen(3000,function(){
console.log('127.0.0.1服务器已启动');
});
1.3 req 请求对象
只要服务器接收到了客户端的请求,就会调用通过 server.on() 为服务器绑定的request事件处理函数
如果想在事件处理函数中访问与客户端相关的数据或属性,可使用如下方法:
//1.导入 http 模块
const http = require('http');
// 2.创建服务器实例对象
const server = http.createServer();
server.on('request',(req) => {
//req:请求对象,包含了与客户端相关的数据和属性
//req.url:客户端请求的 URL 地址
//req.method:客户端的 method 请求类型
const str = `Your request url is ${req.url},and request method is ${req.method}`;
console.log(str);
})
//4.启动服务器
server.listen(3000,function(){
console.log('127.0.0.1:3000服务器已启动');
});
1.4 res 响应对象
在服务器的 request 事件处理函数中,如果想访问与服务器相关的数据或属性,可以使用如下格式:
//1.导入 http 模块
const http = require('http');
// 2.创建服务器实例对象
const server = http.createServer();
server.on('request',(req,res) => {
//req:请求对象,包含了与客户端相关的数据和属性
//req.url:客户端请求的 URL 地址
//req.method:客户端的 method 请求类型
const str = `Your request url is ${req.url},and request method is ${req.method}`;
console.log(str);
//调用 res.end() 向客户端响应一些内容
res.end(str);
})
//4.启动服务器
server.listen(3000,() => {
console.log('127.0.0.1:3000服务器已启动');
});
1.5 防止中文乱码
//1.导入 http 模块
const http = require('http');
// 2.创建服务器实例对象
const server = http.createServer();
server.on('request',(req,res) => {
//req:请求对象,包含了与客户端相关的数据和属性
//req.url:客户端请求的 URL 地址
//req.method:客户端的 method 请求类型
const str = `您请求的 URL 地址是 ${req.url},请求的方法是 ${req.method}`;
console.log(str);
//防止中文乱码
res.setHeader("Content-Type","text/html; charset=utf-8");
//调用 res.end() 向客户端响应一些内容
res.end(str);
})
//4.启动服务器
server.listen(3000,() => {
console.log('127.0.0.1:3000服务器已启动');
});
1.6 根据不同的 url 响应不同的 html 内容
步骤:
- 获取请求的url地址
- 设置默认的响应内容为 404 Not found
- 判断用户请求的是否为 / 或 /index.html 首页
- 判断用户请求的是否为 /about.html 关于页面
- 设置 Content-Type 响应头,防止中文乱码
- 使用 res.end() 把内容响应给客户端
//1.导入 http 模块
const http = require('http');
// 2.创建服务器实例对象
const server = http.createServer();
server.on('request',(req,res) => {
//req:请求对象,包含了与客户端相关的数据和属性
//req.url:客户端请求的 URL 地址
//req.method:客户端的 method 请求类型
//i.获取请求的url地址
const url = req.url;
//ii.设置默认的响应内容为 404 Not found
let content = '<h1>404 Not found!</h1>'
//iii.判断用户请求的是否为 / 或 /index.html 首页
if(url === '/' || url === '/index.html'){
content = '<h1>首页</h1>';
}else if(url === '/about.html'){//iv.判断用户请求的是否为 /about.html 关于页面
content = '<h1>关于页面</h1>';
}
//v.防止中文乱码
res.setHeader("Content-Type","text/html; charset=utf-8");
//vi.调用 res.end() 向客户端响应一些内容
res.end(content);
})
//4.启动服务器
server.listen(3000,() => {
console.log('127.0.0.1:3000服务器已启动');
});
1.7 时钟 web 服务器案例
核心思路:
将文件的时机存放路径,作为每个资源的请求url地址
实现步骤:
- 导入需要的模块
- 创建基本的 web 服务器
- 将资源的请求 url 地址映射为文件的存放路径
- 读取文件内容并响应给客户端
- 优化资源的请求路径
//1.导入 所需 模块
const http = require('http');
const fs = require('fs');
const path = require('path');
// 2.创建服务器实例对象
const server = http.createServer();
server.on('request', (req, res) => {
//req:请求对象,包含了与客户端相关的数据和属性
//req.url:客户端请求的 URL 地址
//req.method:客户端的 method 请求类型
//获取请求的url地址
const url = req.url;
//将资源的请求 url 地址映射为文件的存放路径
// const fpath = path.join(__dirname, url);
//预定义一个空白文件存放路径
let fpath = '';
if(url === '/'){
fpath = path.join(__dirname,'./clock/index.html');
}else{
fpath = path.join(__dirname,'./clock',url);
}
//读取文件内容并响应给客户端
fs.readFile(fpath, 'utf8', (err, dataStr) => {
if (err) {
return res.end('404 Not found!');
}
//调用 res.end() 向客户端响应一些内容
res.end(dataStr);
});
})
//4.启动服务器
server.listen(3000, () => {
console.log('127.0.0.1:3000服务器已启动');
});
1.8 示例1
什么是路径分发?
路径分发也称之为路由, 就是根据不同的请求路径返回不同的数据
如何根据不同的请求路径返回不同的数据?
- 通过请求监听方法中的request对象, 我们可以获取到当前请求的路径
- 通过判断请求路径的地址就可以实现不同的请求路径返回不同的数据
示例,
let http = require("http");
// 1.创建一个服务器实例对象
let server = http.createServer();
// 2.注册请求监听
/*
request对象其实是http.IncomingMessage 类的实例
response对象其实是http.ServerResponse 类的实例
* */
server.on("request", (req, res) => {
res.writeHead(200, {
"Content-Type": "text/plain; charset=utf-8"
});
// console.log(req.url);
if (req.url.startsWith("/index")) {
// 注意点: 如果通过end方法来返回数据, 那么只会返回一次
// res.end("首页1");
// res.end("首页2");
// 注意点: 如果通过write方法来返回数据, 那么可以返回多次
//write方法不具备结束本次请求的功能, 所以还需要手动的调用end方法来结束本次请求
res.write("首页1");
res.write("首页2");
res.end();
} else if (req.url.startsWith("/login")) {
res.end("登录");
} else {
res.end("没有数据");
}
});
// 3.指定监听的端口
server.listen(3000);
1.9 示例2-- 响应完整页面
拿到用户请求路径之后, 只需要利用fs模块将对应的网页返回即可
let http = require("http");
let path = require("path");
let fs = require("fs");
// 1.创建一个服务器实例对象
let server = http.createServer();
// 2.注册请求监听
server.on("request", function(req, res) {
// if (req.url.startsWith("/index")) {
// let filePath = path.join(__dirname, "www", "index.html");
// let filePath = path.join(__dirname, "www", req.url);
// fs.readFile(filePath, "utf8", (err, content) => {
// if (err) {
// res.end("Server Error");
// }
// res.end(content);
// });
// readFile(req, res);
// } else if (req.url.startsWith("/login")) {
// let filePath = path.join(__dirname, "www", req.url);
// fs.readFile(filePath, "utf8", (err, content) => {
// if (err) {
// res.end("Server Error");
// }
// res.end(content);
// });
// readFile(req, res);
// } else {
// res.writeHead(200, {
// "Content-Type": "text/plain; charset=utf-8"
// });
// res.end("没有数据");
// }
readFile(req, res);
});
// 3.指定监听的端口
server.listen(3000);
//将相同代码进行封装
function readFile(req, res) {
let filePath = path.join(__dirname, "www", req.url);
fs.readFile(filePath, "utf8", function(err, content) {
if (err) {
res.end("Server Error");
}
res.end(content);
});
}
1.10 Web服务器输出内容
于我们而言,用的最多的就是用Node构建一个服务器,并且输出内容,内容输出绝大多数为JSON数据
var http = require('http');
var onRequest = function(request, response) {
console.log('Request received');
response.writeHead(200, { 'Content-Type': 'text/plain' });
// response.write('Hello from out application');
response.end('Hello from out application');
}
var server = http.createServer(onRequest);
server.listen(3000, '127.0.0.1');
console.log('Server started on localhost port 3000');
上述代码我们完成了一个文本信息的输出,访问如下
http://localhost:3000/
我们还可以输出JSON格式的数据
var http = require('http');
var onRequest = function(request, response) {
console.log('Request received');
response.writeHead(200, { 'Content-Type': 'application/json' });
// response.write('Hello from out application');
var myObj = {
name: "itbaizhan",
job: "learn",
age: 27
};
response.end(JSON.stringify(myObj));
}
var server = http.createServer(onRequest);
server.listen(3000, '127.0.0.1');
console.log('Server started on localhost port 3000');
当然,个别时候,我们可能需要接受一个服务器返回的页面,例如,支付相关的返回一般都是返回一个页面直接渲染
var http = require('http');
var fs = require('fs');
var onRequest = function(request, response) {
console.log('Request received');
response.writeHead(200, { 'Content-Type': 'text/html' });
var myReadStream = fs.createReadStream(__dirname + '/index.html', 'utf8');
// response.write('Hello from out application');
myReadStream.pipe(response);
}
var server = http.createServer(onRequest);
server.listen(3000, '127.0.0.1');
console.log('Server started on localhost port 3000');
1.11 动态网站--示例
index.html
<form action="./info.html" method="post">
<input type="text" name="userName">
<input type="submit" value="查询">
</form>
info.html
<ul>
<!--<li>姓名: !!!name!!!</li>
<li>性别: !!!gender!!!</li>
<li>年龄: !!!age!!!</li>-->
<!-- 模板语法 -->
<li>姓名:
<%=name%>
</li>
<li>性别:
<%=gender%>
</li>
<li>年龄:
<%=age%>
</li>
</ul>
我们需要通过 npm install art-template --save 命令,安装 art-template
http.js
let http = require("http");
let path = require("path");
let fs = require("fs");
let url = require("url");
let queryString = require("querystring");
let template = require("art-template");
let persons = {
"lisi": {
name: "lisi",
gender: "male",
age: "33"
},
"zhangsan": {
name: "zhangsan",
gender: "female",
age: "18"
}
};
// 1.创建一个服务器实例对象
let server = http.createServer();
// 2.注册请求监听
server.on("request", (req, res) => {
// 如果为GET方式且以/index开头
if (req.url.startsWith("/index") && req.method.toLowerCase() === "get") {
//将返回的路径转为对象
let obj = url.parse(req.url);
//拼接路径
let filePath = path.join(__dirname, obj.pathname);
// 加载文件
fs.readFile(filePath, "utf8", (err, content) => {
if (err) {
res.writeHead(404, {
"Content-Type": "text/plain; charset=utf-8"
});
res.end("Page Not Found");
}
// 成功--返回加载成功的内容
res.writeHead(200, {
"Content-Type": "text/html; charset=utf-8"
});
res.end(content);
});
} //如果为POST请求 且以/info开头
else if (req.url.startsWith("/info") && req.method.toLowerCase() === "post") {
//接收数据
let params = "";
req.on("data", (chunk) => {
params += chunk;
});
//数据接收完毕后
req.on("end", () => {
//解析post参数,并将其转换为对象
let obj = queryString.parse(params);
// console.log(obj);
//查询相应的信息
let per = persons[obj.userName];
// console.log(per);
//将返回的路径转为对象
let filePath = path.join(__dirname, req.url);
/*
fs.readFile(filePath, "utf8", function (err, content) {
if(err){
res.writeHead(404, {
"Content-Type": "text/plain; charset=utf-8"
});
res.end("Page Not Found");
}
content = content.replace("!!!name!!!", per.name);
content = content.replace("!!!gender!!!", per.gender);
content = content.replace("!!!age!!!", per.age);
res.end(content);
});
*/
let html = template(filePath, per);
res.writeHead(200, {
"Content-Type": "text/html; charset=utf-8"
});
res.end(html);
});
}
});
// 3.指定监听的端口
server.listen(3000);