什么是客户端与服务端
在网络节点中,负责消费资源的电脑,叫做客户端;负责对外提供网络资源的电脑叫做服务器
http模块是Nodejs官方提供的、用来创建web服务器的模块。通过http模块提供的http.createServe()
方法,就能方便的把一台普通的电脑变成一台web服务器,从而对外提供web资源服务。
服务器和普通电脑的区别在于,服务器上安装了web服务器软件,例如:IIS、Apache等。通过安装这些服务器软件,就能把一台普通的电脑变成台web服务器。
在Nodejs中,并不需要第三方web服务器软件,因为可以基于nodejs自带的http模块,通过几行简单的代码,就能轻松的手写一个服务器软件,从而对外提供web服务
// 导入http模块
const http = require('http')
// 创建web服务器实例
const server = http.createServer()
// 为web服务器绑定request事件,监听客户端请求
server.on('request', function (req, res) {
// req是请求对象,包含于客户端相关的数据和属性,例如req.url表示客户端请求的URL地址,req.method是客户端的method请求类型
console.log('someone visit our web server');
const str1 = `Your request url is ${req.url},and request method is ${req.method}`
console.log(str1);
const str2 = `您请求的URL地址是${req.url},请求的method类型为${req.method}`
// 设置响应头,防止中文乱码(告诉浏览器,服务器这边将返回text/html类型的数据)
res.setHeader('Content-Type','text/html; charset=utf-8')
// 向客户端发送指定的内容,并结束这次请求的处理过程
res.end(str2);
})
// 启动服务器
server.listen(8080, function () {
console.log('server running at http://127.0.0.1:8080')
})
只要服务器接收到了客户端的请求,就会调用server.on()为服务器绑定的request事件处理函数。可以通过如下的方式访问与客户端相关的数据或属性。
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);
})
需要注意的是req.url输出的是端口号后面的地址,并不是一个完整地址
在服务器的request事件处理函数中,如果想访问服务器相关的数据或属性,可以使用如下的方式;
// 为web服务器绑定request事件,监听客户端请求
server.on('request', function (req, res) {
// req是请求对象,包含于客户端相关的数据和属性,例如req.url表示客户端请求的URL地址,req.method是客户端的method请求类型
console.log('someone visit our web server');
const str = `Your request url is ${req.url},and request method is ${req.method}`
// 向客户端发送指定的内容,并结束这次请求的处理过程
res.end(str);
})
当调用res.end()方法向客户端发送中文内容的时候会出现乱码问题,此时需要手动设置内容的编码,这里可以通过设置响应头 Content-Type 的值为text/html; charset=utf-8 解决中文乱码问题
res.setHeader(‘Content-Type','text/html;charset=utf-8')
// 为web服务器绑定request事件,监听客户端请求
server.on('request', function (req, res) {
// req是请求对象,包含于客户端相关的数据和属性,例如req.url表示客户端请求的URL地址,req.method是客户端的method请求类型
console.log('someone visit our web server');
const str = `您请求的URL地址是${req.url},请求的method类型为${req.method}`
res.setHeader('Content-Type','text/html; charset=utf-8')
// 向客户端发送指定的内容,并结束这次请求的处理过程
res.end(str);
})
1、获取post请求,请求头为application/x-www-form-urlencoded,表单类型的数据
const http = require('http')
const queryString = require('query-string') // 解析查询字符串为js对象或者js对象转查询字符串
const server = http.createServer()
server.on('request', function (req, res) {
// console.log(req)
// 设置编码,防止中文乱码
res.setHeader('Content-Type', 'text/html; charset=utf-8')
// 处理跨域
res.setHeader("Access-Control-Allow-Origin", "*");
let data = ''
let result = ''
// 处理数据
// 可以通过if(req.method=='post')或者if(req.url=='./xxx')来决定获取哪个请求或者路由的数据,我这为简便就不写了
req.on('data', chunk => {
// 请求头类型为application/x-www-form-urlencoded/charset=utf-8的形式
// 将每次收到的数据片段拼接到 data 变量中
console.log(chunk, "chunk ================="); // chunk是一个buffer类型的数据
// 通过拼接可以一步转buffer为普通字符串,或者调用一下toString()方法也可以转为字符串
data += chunk
// data = chunk.toString()
console.log(data, "data ===============");
// 将查询字符串转为js对象
result = queryString.parse(data)
console.log(result, "result ============")
})
// 返回数据
req.on('end', () => {
res.end(JSON.parse(result)) // 将js对象转为json对象返回
})
})
server.listen(8080, function () {
console.log("服务器启动成功,监听8080端口...")
})
2、获取get请求,请求头为application/x-www-form-urlencoded,表单类型的数据
对于get请求,一般参数会在url上,所以要先从url上截取参数
const http = require('http')
const server = http.createServer()
const url = require('url') // 处理url路径的模块,这里用来截取查询字符串
server.on('request', function (req, res) {
// 设置编码,防止中文乱码
res.setHeader('Content-Type', 'text/html; charset=utf-8')
// 处理跨域
res.setHeader("Access-Control-Allow-Origin", "*");
// 参数放在url中,从url截取字符串并转为js对象
const queryObject = url.parse(req.url, true).query;
res.end(JSON.stringify(queryObject))
})
server.listen(8080, function () {
console.log("服务器启动成功,监听8080端口...")
})
3、如果接收到的参数是json字符串,那么同理,先想办法将json字符串转为js对象(例如JSON.parse()方法将json对象转为js对象),再进行其他处理并返回啥的…
对于get请求,由于不存在请求体,所以需要将json数据拼接在url上,对于参数少的情况这种办法行得通,但如果数据过多,那么会导致url很长,浏览器导航栏会截取部分url,导致出现问题,所以最好还是使用post请求来处理json数据。
如下:
const http = require('http')
const server = http.createServer()
server.on('request', function (req, res) {
console.log(req.url);
// 设置编码,防止中文乱码
// res.setHeader('Content-Type', 'text/html; charset=utf-8')
// 处理跨域
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "*");
res.setHeader("Access-Control-Allow-Headers", "Content-Type,XFILENAME,XFILECATEGORY,XFILESIZE");
let data = ''
// 可以通过if(req.method=='post')或者if(req.url=='./xxx')来决定获取哪个请求或者路由的数据,我这为简便就不写了
// 获取数据
req.on('data', chunk => {
// 请求头类型为application/json;charset=utf-8的形式
// 将每次收到的数据片段拼接到 data 变量中
console.log(chunk, "chunk ================="); // chunk是一个buffer类型的数据
// 通过拼接可以一步转buffer为普通字符串,或者调用一下toString()方法也可以转为字符串
data += chunk
// data = chunk.toString()
console.log(data, "data ===============");
// 使用JSON.parse()将json转为js对象,对数据进行一些处理啥的
// ...
})
req.on('end', () => {
// 返回json数据
res.end(data)
})
})
server.listen(8080, function () {
console.log("服务器启动成功,监听8080端口...")
})
1、核心实现步骤
(1)获取请求的url地址
(2)设置下默认的相应内容为 ’404 Nod found’
(3)判断用户请求的是否为/ 或者 其他url地址
(4)判断用户请求的是否为指定页面
(5)设置Content-Type响应头,防止中文乱码
(6)使用res.end()把内容响应给客户端
server.on('request', (req, res) => {
// 1、获取请求的url地址
const url = req.url
// 2、设置默认的内容为404 not found
let content = '404 Not Found
'
// 3、判断用户请求的url地址,显示对应的页面
if(url === '/' || url === '/index.html'){
content = '首页
'
}else if(url === '/about.html'){
content = '关于页面
'
}
// 4、中文乱码处理
res.setHeader('Content-Type','text/html; charset=utf-8')
// 5、服务器响应数据
res.end(content)
})
有如下js/html/css实现的动态页面,目录结构如下
- HttpTest根目录
HttpTest/web
HttpTest/web/main.html
HttpTest/web/main.css
HttpTest/web/main.js
HttpTest/server.js
实现的效果为:
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>Documenttitle>
<link rel="stylesheet" href="./main.css">
head>
<body>
<div class="father">
<div class="son">
div>
div>
<script src="./main.js">script>
body>
html>
.father {
width: 300px;
height: 300px;
background-color: skyblue;
}
.son {
width: 100px;
height: 100px;
background-color: pink;
}
window.onload = function () {
var father = document.getElementsByClassName('father')[0];
father.onclick = function () {
alert('天蓝色')
}
var son = document.getElementsByClassName('son')[0]
son.onclick = function (event) {
alert('粉色')
event.stopPropagation();
}
}
const fs = require('fs')
const path = require('path')
const http = require('http')
const server = http.createServer()
// 为web服务器绑定request事件,监听客户端请求
server.on('request',(req,res)=>{
// 获取客户端请求的url地址
let url = req.url;
// console.log(url);
// url值有如下:
/**
* /web/main.html
* /web/main.css
* /web/main.js
*/
// 将资源的请求url地址映射为文件的存放路径
const fpath = path.join(__dirname,url)
// console.log(fpath);
// 根据映射过来的路径读取文件内容
fs.readFile(fpath,(err,data) => {
// 如果读取失败,向客户端响应固定的‘错误信息’
if(err) return res.end('404 not found')
// 如果读取成功,将读取成功的内容响应给客户端
res.end(data)
})
})
上述例题中的访问过程如下图:
通过访问http://127.0.0.1:8080/web/main.html可以访问到页面,但url地址中需要手动添加一个web文件夹,显得url很长,下面通过优化资源请求访问路径来缩短url
const fs = require('fs')
const path = require('path')
const http = require('http')
const server = http.createServer()
// 为web服务器绑定request事件,监听客户端请求
server.on('request',(req,res)=>{
// 获取客户端请求的url地址
let url = req.url;
console.log(url);
// url值为如下:
/**
* /web/main.html
* /web/main.css
* /web/mian.js
*/
// 将资源的请求url地址映射为文件的存放路径
// const fpath = path.join(__dirname,url)
// =====================================
// 优化请求路径
let fpath = ''
if(url === '/'){
fpath = path.join(__dirname,'./web/main.html')
}else {
fpath = path.join(__dirname,'./web',url)
}
console.log(fpath);
// =====================================
// 根据映射过来的路径读取文件内容
fs.readFile(fpath,(err,data) => {
// 如果读取失败,向客户端响应固定的‘错误信息’
if(err) return res.end('404 not found')
// 如果读取成功,将读取成功的内容响应给客户端
res.end(data)
})
})
// 启动服务器,监听8080端口
server.listen('8080',() => {
console.log('server running at http://127.0.0.1:8080');
})
这样就可以直接通过输入路径
127.0.0.1/main.html
来访问到页面,而不用在路径中手动添加一个web