http服务器_http服务器
http 服务器
安装ts-node-dev
npm install ts-node-dev -g
项目准备
在项目目录中输入以下命令
yarn init -y
yarn add --dev @types/node
http初体验
import * as http from 'http';
const server = http.createServer();
server.on('request',(request,response)=>{
console.log('有人请求了');
response.end('hi')
})
server.listen(8888)
request
从文档中我们可以知道 request是InComingMessage的实例
request拥有以下属性
- header
- url
- httpVersion
- ······
从stream.Readablel类中继承了以下事件
- data
- end
- error
- ······
import * as http from 'http';
import {IncomingMessage, ServerResponse} from 'http';
const server = http.createServer();
server.on('request', (request:IncomingMessage, response:ServerResponse) => {
console.log(request.method);
console.log(request.url);
console.log(request.headers);
response.end('hi')
});
server.listen(8888);
发送一个get请求
$ curl http://localhost:8888/yyy
发送post请求
$ curl -v -d name="great" http://localhost:8888
但是没有看到post上去的数据 那么如何获取到这些数据?
import * as http from 'http';
import {IncomingMessage, ServerResponse} from 'http';
const server = http.createServer();
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
console.log(request.method);
const array = [];
request.on('data', (chunk) => {
array.push(chunk);
});
request.on('end', () => {
const data = Buffer.concat(array).toString();
console.log(data);
response.end('hi');
});
});
server.listen(8888);
response
从文档中我们可以知道 request是ServerResponse的实例
response拥有以下方法
- getHeader
- setHeader
- end
- write
- ······
response拥有以下属性
- statusCode
- ······
import * as http from 'http';
import {IncomingMessage, ServerResponse} from 'http';
const server = http.createServer();
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
response.statusCode = 404;
response.setHeader('GG',`I am 123`)
response.write('1\n')
response.write('2\n')
response.write('3\n')
response.end()
});
server.listen(8888);
根据不同的url返回不同的文件
import * as http from 'http';
import {IncomingMessage, ServerResponse} from 'http';
import * as fs from 'fs';
import * as p from 'path';
const server = http.createServer();
const publicDir = p.resolve(__dirname,'public')
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
const {url, method, headers} = request;
switch (url) {
case '/index.html':
response.setHeader('content-Type','text/html;charset=utf-8')
fs.readFile(p.resolve(publicDir,'index.html'),(error,data)=>{
if(error) throw error
response.end(data.toString())
});
break;
case '/style.css':
response.setHeader('content-Type','text/css;charset=utf-8')
fs.readFile(p.resolve(publicDir,'style.css'),(error,data)=>{
if(error) throw error
response.end(data.toString())
});
break;
case '/main.js':
response.setHeader('content-Type','text/javascript;charset=utf-8')
fs.readFile(p.resolve(publicDir,'main.js'),(error,data)=>{
if(error) throw error
response.end(data.toString())
});
break;
}
});
server.listen(8888);
处理查询参数
查询参数也成为了路径 如何解决这个问题?
import * as http from 'http';
import {IncomingMessage, ServerResponse} from 'http';
import * as fs from 'fs';
import * as p from 'path';
import * as url from 'url';
const server = http.createServer();
const publicDir = p.resolve(__dirname, 'public');
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
const {url:path, method, headers} = request;
const object = url.parse(path)
console.log(object)
switch (path) {
case '/index.html':
response.setHeader('content-Type', 'text/html;charset=utf-8');
fs.readFile(p.resolve(publicDir, 'index.html'), (error, data) => {
if (error) throw error;
response.end(data.toString());
});
break;
case '/style.css':
response.setHeader('content-Type', 'text/css;charset=utf-8');
fs.readFile(p.resolve(publicDir, 'style.css'), (error, data) => {
if (error) throw error;
response.end(data.toString());
});
break;
case '/main.js':
response.setHeader('content-Type', 'text/javascript;charset=utf-8');
fs.readFile(p.resolve(publicDir, 'main.js'), (error, data) => {
if (error) throw error;
response.end(data.toString());
});
break;
}
});
server.listen(8888);
我们使用pathname就可以过滤查询参数
因此
import * as http from 'http';
import {IncomingMessage, ServerResponse} from 'http';
import * as fs from 'fs';
import * as p from 'path';
import * as url from 'url';
const server = http.createServer();
const publicDir = p.resolve(__dirname, 'public');
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
const {url:path, method, headers} = request;
const {pathname,search} = url.parse(path)
console.log(pathname);
switch (pathname) {
case '/index.html':
response.setHeader('content-Type', 'text/html;charset=utf-8');
fs.readFile(p.resolve(publicDir, 'index.html'), (error, data) => {
if (error) throw error;
response.end(data.toString());
});
break;
case '/style.css':
response.setHeader('content-Type', 'text/css;charset=utf-8');
fs.readFile(p.resolve(publicDir, 'style.css'), (error, data) => {
if (error) throw error;
response.end(data.toString());
});
break;
case '/main.js':
response.setHeader('content-Type', 'text/javascript;charset=utf-8');
fs.readFile(p.resolve(publicDir, 'main.js'), (error, data) => {
if (error) throw error;
response.end(data.toString());
});
break;
}
});
server.listen(8888);
错误处理
import * as http from 'http';
import {IncomingMessage, ServerResponse} from 'http';
import * as fs from 'fs';
import * as p from 'path';
import * as url from 'url';
const server = http.createServer();
const publicDir = p.resolve(__dirname, 'public');
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
const {url: path, method, headers} = request;
const {pathname, search} = url.parse(path);
const fileName = pathname.substr(1);
response.setHeader('content-Type', `text/html;charset=utf-8`);
fs.readFile(p.resolve(publicDir, fileName), (error, data) => {
if (error) {
if (error.errno === -4058 || error.errno === -2) {
response.statusCode = 404;
fs.readFile(p.resolve(publicDir, '404.html'), (error, data) => {
response.end(data);
});
} else if(error.errno === -21){
response.statusCode = 403
response.end('没有权限')
}else {
response.statusCode = 500;
console.log(error);
response.end('服务器炸了');
}
} else {
response.end(data);
}
});
});
server.listen(8888);
处理非get请求
import * as http from 'http';
import {IncomingMessage, ServerResponse} from 'http';
import * as fs from 'fs';
import * as p from 'path';
import * as url from 'url';
const server = http.createServer();
const publicDir = p.resolve(__dirname, 'public');
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
const {url: path, method, headers} = request;
const {pathname, search} = url.parse(path);
if (method !== 'GET') {
response.statusCode = 405;
response.end();
return;
}
let fileName = pathname.substr(1);
if (fileName === '') {
fileName = 'index.html';
}
response.setHeader('content-Type', `text/html;charset=utf-8`);
fs.readFile(p.resolve(publicDir, fileName), (error, data) => {
if (error) {
if (error.errno === -4058 || error.errno === -2) {
response.statusCode = 404;
fs.readFile(p.resolve(publicDir, '404.html'), (error, data) => {
response.end(data);
});
} else if (error.errno === -21) {
response.statusCode = 403;
response.end('没有权限');
} else {
response.statusCode = 500;
console.log(error);
response.end('服务器炸了');
}
} else {
response.end(data);
}
});
});
server.listen(8888);
添加缓存选项
如果我们经常加载一个网页 那么多次请求会印象效率 因此我们可以添加缓存 然后页面就不必被每次加载 这样可以提升性能
import * as http from 'http';
import {IncomingMessage, ServerResponse} from 'http';
import * as fs from 'fs';
import * as p from 'path';
import * as url from 'url';
const server = http.createServer();
const publicDir = p.resolve(__dirname, 'public');
server.on('request', (request: IncomingMessage, response: ServerResponse) => {
const {url: path, method, headers} = request;
const {pathname, search} = url.parse(path);
if (method !== 'GET') {
response.statusCode = 405;
response.end();
return;
}
let fileName = pathname.substr(1);
if (fileName === '') {
fileName = 'index.html';
}
response.setHeader('content-Type', `text/html;charset=utf-8`);
fs.readFile(p.resolve(publicDir, fileName), (error, data) => {
if (error) {
if (error.errno === -4058 || error.errno === -2) {
response.statusCode = 404;
fs.readFile(p.resolve(publicDir, '404.html'), (error, data) => {
response.end(data);
});
} else if (error.errno === -21) {
response.statusCode = 403;
response.end('没有权限');
} else {
response.statusCode = 500;
console.log(error);
response.end('服务器炸了');
}
} else {
response.setHeader('Cache-Control',`public, max-age=31536000`)
response.end(data);
}
});
});
server.listen(8888);