Node.js HTTP服务器
1. 最简单版本GET/POST/…
const http = require('http')
const hostname='localhost' //`127.0.0.1`
const port = 3000
const server = http.createServer((req, res) => {
if (req.method=='GET'){//处理POST请求
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('你好世界\n')
}
else if (req.method=='POST'){//处理POST请求
...
}
})
server.listen(port, () => {
console.log(`服务器运行在 http://${hostname}:${port}/`)
})
- 客户端地址 http://localhost:3000
2. 处理HTTP GET请求参数
对于https://cn.bing.com/search?q=baidu&cvid=9ad 这种URL,可从中拆分出pathname
、querystring
。
- pathname:
/search
- querystring :
?q=baidu&cvid=0
需引入url
模块
const url = require('url'); // 引用url地址模块
server.on('request', (req, res) => {
if (req.method === "GET") {
console.log(req.url); // /search?q=baidu&cvid=9ad
let { query, pathname } = url.parse(req.url, true)
console.log(pathname);// /search
console.log(query);// /[Object: null prototype] { q: 'baidu', cvid: '9ad' }
//...
if(pathname=='/'){
res.writeHead(200, { "Content-Type": 'text/html; charset=utf-8' });//注意编码UTF
// 返回主页内容
res.end(`<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>http</title></head>
<body>?todo?</body></html>`)
}
else if (pathname === '/images/a.jpg') {
res.writeHead(200, { "Content-Type": "image/jpeg" });
readFile(__dirname + req.url, (err, buffer) => {
if (err) throw err;
res.write(buffer);
res.end();
});
}
}
}
//...
-
客户端地址 http://localhost:3000/seaarch?q=baidu&id=0,后台打印出
query
就是一个object。很容易继续处理。 -
为了保险起见,建议使用
pathname
进行路由匹配/xx
-
可以利用mime模块根据路径返回资源的类型
const mime = require('mime'); // 引用第三方模块 //.. let type = mime.getType(realPath); res.writeHead(200, {'content-type': type});
3 解析POST数据
const querystring = require('querystring')
server.on('request', (req, res) => {
//...
if (req.method == "POST") {
let postParams = '';
// 监听参数传输事件
req.on('data', params => {
postParams += params;
});
// 监听参数传输完毕事件
req.on('end', () => {
console.log(postParams)// name=abc&age=123
console.log(querystring.parse(postParams,"&", "="));// 把字符串格式转换为对象格式
// [Object: null prototype] { name: 'abc', age: '123' }
})
//...
}
这里需要监听request对象的事件data
&on
事件,获取所有的post数据,然后用querystring
转换为对象格式。
4 静态资源处理
我们有时候需要处理前端静态资源,如html\js\css\png等文件,统一放在public目录下;
const http = require('http');
const { readFile } = require('fs/promises');
const path = require('path')
const url = require('url'); // 引用url地址模块
const mime = require('mime') // npm i mime
const port = 8080;
const server = http.createServer();
server.on("request", async (req, res) => {
console.log(req.url)
let { query, pathname } = url.parse(req.url, true)
// console.log(pathname);// /search
// console.log(query);// /[Object: null prototype] { q: 'baidu', cvid: '9ad' }
if (req.method === "GET") {
if (pathname === "/") {
pathname = 'index.html'
}
pathname = path.join(__dirname, 'public', pathname)
const type = mime.getType(pathname)
console.log("GET", pathname, type);
try {
res.writeHead(200, {
"Content-Type": type + ';' + 'charset=utf8'
});
let buffer = null;
if (type.startsWith("text/")) { // 文本文件
buffer = await readFile(pathname, 'UTF-8')
} else {// binary文件
buffer = await readFile(pathname);
}
res.write(buffer);
res.end();
} catch (err) { // 文件不存在!404.HTML
console.log("FILE NOT EXIST:", pathname)
res.writeHead(404, { "Content-Type": 'text/html;charset=utf8' });
res.end(await readFile('./public/404.html', 'UTF-8'))
return;
}
} else if (req.method === "POST" && req.url === "/register") {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json; charset=utf8');
res.end(`{code:'ok'}`);
}
});
const host = "localhost";
server.listen(port, () => {
console.log(`服务器运行在 http://${host}:${port}/`);
});