笔记目录
小概
本章的学习内容:如何用node开启http网络服务,http.createServer 的回调函数中的两个参数request、response,静态网络请求处理,
1. node实现web网络服务
利用node.js创建一个简单web服务,这个服务就可以处理来自客户端的HTTP请求
- 导入http模块(node内置模块)
- 创建web服务(可以在回调函数中处理客户端发过来的请求)
- 启动这个服务并监听
//1. 导入http模块
const http = require('http');
//2.http.createServer方法创建服务
const server = http.createServer((req, res) => {
res.end('Hello, Node.js!');
//3. 将这个服务启动
// listen 监听
// 监听的端口号
// 回调函数 这个服务成功启动之后,就会将执行这个回调函数
server.listen(80, ()=>{
console.log('服务已经成功启动');
});
});
1.运行服务后会一直运行,监听来自客户端的请求。
2.与我们的计算机在同一网络的电脑都可以通过http协议来访问(浏览器,ajax,postman等)
3.createServer传入的回调函数的执行时机:服务器启动后,一旦接收到客户端的http请求 这个回调函数就会被立即执行,
4.在没有设置限制的情况下,访问服务端的URL只要ip地址和端口正确不管后面跟什么形式的URL都可以访问这个服务
5.计算机端口作用:一台计算机可能又很多服务,要求不同的服务运行在不同的端口,区别计算器上的不同的服务
6.http协议默认端口:80 https协议默认端口:443
2. http.createServer()回调函数中的req参数
创建服务方法,传递一个回调函数 http.createServer((req,res)=>{});
第一个参数:req(request 请求),注意req只是规范写法,它是一个形参,可以自定义命名。
req的属性:
- req.herders :这个属性保存的是本次请求 客户端发给服务器的数据中的 请求头
- req.url:这个属性可以获取客户端请求服务端的时候,url部分 /(包含/)之后的部分.
- req.method:这个是属性可以获取客户端请求服务端的方法 get/post
const http = require('http');
http.createServer((req, res) => {
//回调函数第1个参数: req
//这个对象中封装了本次请求 客户端发给服务端的数据.
//1. req.headers 这个属性中保存的是本次请求,客户端发给服务端的数据中的 请求头.
//2. req.url 这个属性可以获取客户端请求服务端的时候,URL部分 切记 是 / 开头
//3. req.method 这个属性可以获取客户端请求服务端的方法 get post
//4. 获取客户端的ip地址
//
console.log('接收到来自客户端的请求啦...客户端的IP地址是:'+getClientIp(req));
//console.log(req);
res.end('Hello, Node.js!');
}).listen(80, () => console.log('服务启动成功'));
function getClientIp(req) {
//不同的浏览器 是把ip地址放在不同的地方.
return req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress;
};
注意req.method获取的方法是大写的GET/POST,getClinetIp(req)方法可以返回客户端IP地址。
3. http.createServer()回调函数中的res参数
第二个参数:res (response 响应)
res的属性
- res.setHeader(‘属性名’,‘值’): 向响应头写入数据
1.1 res.setHeader (‘Content-Type’,‘text/html;charset=utf-8’)
Content-Type,告诉浏览器,浏览器发给你的数据的类型 text/plain (纯文本 浏览器会原样显示 ),text/html (html文档 浏览器会当做html渲染)- res.statusCode :设置响应状态码
- res.write():向响应体中追加数据
- res.end() :代表请求处理结束,如果不传参数就表示结束请求,传递了参数就表示追加数据到响应体并结束请求处理。
const http = require('http');
http.createServer((req, res) => {
//向响应头中写入数据
//res.setHeader('Server', 'Node.js');
//响应头: Content-Type
//告诉浏览器,服务端发给你的数据的类型. 以及发给你的数据的编码.
// text/plain 纯文本 浏览器会原样显示
// text/html html文档 浏览器会当做html渲染
res.setHeader('Content-Type', 'text/html;charset=utf-8');
res.statusCode = 200;
//向响应体中追加数据.
//传入的参数 只能是字符串或者Buffer
res.write('<h1>上午不睡下午崩溃</h1>');
res.write('<h1>上午睡了,下午也崩溃</h1>');
res.write('<h1>为啥白天小鸡啄米,晚上精神抖擞?</h1>');
//代表请求处理结束.
//如果不传参数,就代表结束请求
//如果传递了参数。 就代表传递的数据追加到响应体中的.
res.end('Hello Node.js!');
// res.end();
// res.end('Hello Node.js!');
}).listen(80, () => console.log('服务启动成功'))
res 表示的是response响应的意思,用来设置服务端响应数据,响应分为响应头和响应体两个部分。在往响应体丢数据的时候,记得设置res.setHeader(‘Content-Type’,‘数据类型’)。常见的res.statusCode =200 201 404 500…
4. 判断请求返回对应响应
判断请求url的/后面的内容和method类型,执行响应的响应操作
const http = require('http');
const fs = require('fs');
const path = require('path');
http.createServer((req, res) => {
//1. 获取浏览器请求服务器的时候所带的URL
const url = req.url.toLowerCase();
//2. 判断这个URL的值 根据不同的值 返回不同的内容.
if(url == '/index.html'){
res.setHeader('Content-Type','text/html;charset=utf-8');
res.end('我是首页');
}else if(url == '/login.html'){
res.setHeader('Content-Type','text/html;charset=utf-8');
res.end('我是登录页');
}else if(url == '/bg.jpg'){
//返回一个图片
//需要将图片读取出来,图片数据写到响应体中,返回给浏览器.
fs.readFile(path.join(__dirname, 'public/dog.jpg'), (err, data) => {
if(err){
res.statusCode = 500;
res.end();
}else{
//图片数据读取成功:
//向响应体中写入数据,
res.setHeader('Content-Type', 'image/jpeg');
res.end(data);
}
});
}else{
//设置响应状态代码为404
res.statusCode = 404;
res.end();
}
}).listen(80, ()=>console.log('服务启动成功'))
node.js静态资源托管
const http = require('http');
const fs = require('fs');
const path = require('path');
http.createServer((req, res) => {
//1. 为了兼容客户端的大小写,我先将url和method统统转换为小写.
req.url = req.url.toLowerCase();
req.method = req.method.toLowerCase();
res.setHeader('Content-Type', 'text/html;charset=utf-8');
// /dog.jpg get
//2. 判断URL和Method
if(req.url == '/index.html' && req.method == 'get'){
//我们一般的操作:
//将网页的代码写在一个单独html文件中.
//放回数据的时候,将这个文件读取出来,放到响应体中返回给浏览器.
//当url是 /index.html 并且请求方法是get 的时候,
//将public/index.html文件读取出来,返回给浏览器.
fs.readFile(path.join(__dirname, 'public', 'index.html'), 'utf-8', (err, data) => {
if(err){
res.statusCode = 500;
return res.end();
}
//说明读取成功
res.end(data);
});
}else if(req.url == '/dog.jpg' && req.method == 'get'){
fs.readFile(path.join(__dirname, 'public','dog.jpg'), (err, data) => {
if(err){
res.statusCode = 500;
return res.end();
}
//这里返回的数据是图片jpg
res.setHeader('Content-Type', 'image/jpeg');
res.end(data);
});
}else if(req.url == '/css/index.css' && req.method == 'get'){
fs.readFile(path.join(__dirname, 'public','css/index.css'), (err, data) => {
if(err){
res.statusCode = 500;
return res.end();
}
//这里返回的数据是css
res.setHeader('Content-Type', 'text/css');
res.end(data);
});
}else{
res.statusCode = 404;
res.end();
}
}).listen(80, ()=>console.log('服务启动成功'));
在一个页面中,内部写了很多请求,比如图片路径,css引入链接,js引入链接 等等 这些都会发起网络请求,如果像上面这样把fs.readFile路径写死,当引入了一个base.css的样式,浏览器会发起请求http://127.0.0.1/css/base.css的请求,
解决方法:
const http = require('http');
const fs = require('fs');
const path = require('path');
http.createServer((req, res) => {
//我们发现,要读取的文件的文件名刚刚巧和URL是一样的.
req.url = req.url.toLowerCase();
const filename = path.join(__dirname, 'public', req.url); //path.join 拼接地址 __dirname 表示当前文件
//filname(文件地址)=当前文件+public+URL
fs.readFile(filename, (err, data) =>{
if(err){
//读取的时候,发生了错误.
res.statusCode = 404;
return res.end();
}
//说明读取成功
//a. 设置Content-Type
// 判断1下读取的是什么文件。根据不同的文件 设置不同的Content-Type
// 使用.分隔filename 得到1个数组,这个数组的最后1个元素就是后缀名
const arr = filename.split('.');
const hzm = arr[arr.length-1];
let cType = 'text/html';
switch(hzm){
case 'jpg':
cType = 'image/jpeg';
break;
case 'css':
cType = 'text/css'
break;
case 'png':
cType = 'image/png';
break;
}
//设置响应头.
res.setHeader('Content-Type', cType);
//b. 将读取出来的数据放到响应体,返回给浏览器.
res.end(data);
});
}).listen(80, () => console.log('服务启动成功!'));
5. node内置模块 fs
const fs = require('fs');
const path = require('path');
//操作磁盘上的文件.
//读文件 写文件. 删文件 改文件..... 重命名.
//参数1: 文件的路径.
// const filename = path.join(__dirname, 'data/1.txt');
// const content = `
// 黑马程序员,yyds!!!!!
// `;
// fs.writeFile(filename, content, 'utf-8', err=>{
// if(err) return console.log('写入失败, '+err);
// console.log('写入成功');
// });
//如果文件中已经有内容,那么我们写入的时候,会对内容进行覆盖.
//?????? 追加的效果.
const filename = path.join(__dirname, 'data/1.txt');
//1 先将文件的内容读取出来
fs.readFile(filename, 'utf-8', (err, data) => {
if(err) return console.log('操作失败, '+err);
//data
const newContent = data + '哈哈哈哈,我来了!!!';
fs.writeFile(filename, newContent, 'utf-8', err=>{
if(err) return console.log('操作失败, '+err);
console.log('操作成功');
});
});
总结
本章主要是了解原生node.js的内置模块http,原生http处理网络请求(http.createServer((req,res)=>{}))