Node.js HTTP服务器
1. GET/POST
<pre data-role="codeBlock" data-info="shell" class="language-shell" style="white-space: pre;">
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}/`)
})
</pre>
2. 处理HTTP GET请求参数
对于https://cn.bing.com/search?q=baidu&cvid=9ad 这种URL,可从中拆分出pathname、querystring。
-
pathname: /search
-
querystring : ?q=baidu&cvid=0
需引入url模块
<pre data-role="codeBlock" data-info="shell" class="language-shell" style="white-space: pre;">
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(`
<meta charset="UTF-8"><title>http</title>
?todo?`)
}
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();
});
}
}
}
</pre>
3. 解析POST数据
<pre data-role="codeBlock" data-info="shell" class="language-shell" style="white-space: pre;">
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' }
})
//...
}
</pre>
这里需要监听request对象的事件data&on事件,获取所有的post数据,然后用querystring转换为对象格式。
4. 静态资源处理
<pre data-role="codeBlock" data-info="shell" class="language-shell" style="white-space: pre;">
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}/`);
});
</pre>