简介
net模块太过于麻烦啦,而http模块相对于net的模块就简单多啦。
http模块建立在net模块之上
http模块无须手动管理socket
http模块无须手动组装消息格式
客户端与服务端官网查文档总结
客户端
http.request(url[, options][, callback])
官方文档
https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_http_request_url_options_callback
由于文档太长截图不易,可以去官网去查看
callback
而这个函数指向那呢官方文档中说[http.IncomingMessage](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_class_http_incomingmessage)
啊 就是前面讲到的客户端与服务端官方查文档总结图中的
返回值
示例
const http = require('http');
const request = http.request(
'http://yuanjin.tech:5005/api/movie',
{
method: 'GET',
},
(resp) => {
console.log(resp.headers);
console.log(resp.statusCode);
let result = '';
/**
* 服务器响应数据,是不固定的
* 流式操作
*/
resp.on('data', (chunk) => {
result += chunk.toString('utf-8');
});
resp.on('end', chunk => {
console.log(JSON.parse(result))
})
}
);
/**
* get 协议的 消息体并不是没有,而是空,没有消息体会让服务器以为客户端还没发送完
*/
request.end(); // 表示所有数据写入完毕
服务器
http.createServer([options][, requestListener])
官方文档
示例
const http = require('http');
const URL = require('url')
/**
* 获取请求体
*/
function getRequest(res) {
const urlObj = URL.parse(res.url);
console.log('请求路径', urlObj)
console.log('请求方法', res.method);
console.log('请求头', res.headers);
let body = '';
res.on('data', chunk => {
body += chunk.toString('utf-8');
})
res.on('end', () => {
console.log('请求体', body)
})
}
const serve = http.createServer((res, rep) => {
getRequest(res)
// 响应头
rep.setHeader('a', 'a')
// 响应行
rep.statusCode = '404'
// 响应体
rep.write('hello!!!')
rep.end() // 结束
})
/**
* 监听端口
*/
serve.listen(9000)
serve.on('listening', () => {
console.log('listen server 9000 ')
})
// serve.on('connection', () => {
// console.log('有客户端连接进来')
// })
制作简易静态服务器
const http = require('http');
const URL = require('url');
const path = require('path');
const fs = require('fs')
/**
* 文件或文件夹是否存在
* @param {*} fileName
* @returns
*/
async function getStat(fileName) {
try {
return await fs.promises.stat(fileName)
} catch {
return false;
}
}
/**
* 获取文件内容
* @param {*} url
*/
async function getFileContent(url) {
const urlObj = URL.parse(url);
// console.log(urlObj.pathname);
let fileName = path.resolve(__dirname, urlObj.pathname.substr(1))
let stat = await getStat(fileName)
if(!stat) {
return null;
} else if (stat.isDirectory()) {
/**
* 可能访问的路径是一个文件夹
* 当着文件夹可能是空的
* 也可能里面存放着index.html
* 也可能是一个index.html
*/
fileName = path.resolve(__dirname, urlObj.pathname.substr(1), 'index.html');
stat = await getStat(fileName);
if (stat) {
return await fs.promises.readFile(fileName);
} else {
return null;
}
} else {
return await fs.promises.readFile(fileName)
}
}
/**
* requestListenner
* @param {*} req
* @param {*} res
*/
async function requestListenner (req, res) {
const info = await getFileContent(req.url)
if(info) {
res.write(info)
} else {
res.statusCode = 404;
res.write('Resource is not exist');
}
console.log('有客户端连接')
res.end();
}
const server = http.createServer(requestListenner);
server.listen(9000)
server.on('listening', () => {
console.log('linten server 9000')
})