主题
原生nodejs服务
1. 实现node静态服务
1. 下载安装mime
模块处理请求文件类型
sh
npm init -y
npm install mime
2. 编写代码
js
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
const mime = require('mime'); // 处理请求文件类型
let server = http.createServer((req, res) => {
let { pathname } = url.parse(req.url); // 请求路径解析
console.log(pathname);
// 根据请求路径查找文件
let absFilePath = path.join(__dirname, pathname);
fs.stat(absFilePath, (err, stat) => { // 判断文件是否存在
if (err) { // 路径不存在
return res.end(`Not Found`);
}
if (stat.isDirectory()) { // 若路径是文件夹
// 尝试查找index.html
absFilePath = path.join(absFilePath, "index.html");
// 检查当前目录中是否存在该文件。
fs.access(absFilePath, (err) => {
if (err) { // 文件不存在
res.end(`Not Found`);
} else { // 文件存在
let type = mime.getType(absFilePath); // 取到文件类型
res.setHeader("Content-Type", type + ";charset=utf-8");
fs.createReadStream(absFilePath).pipe(res); // 以流的方式响应客户端
}
});
} else {
// 请求路径不是文件夹,则根据路径名找要查找的文件类型
let type = mime.getType(absFilePath);
res.setHeader("Content-Type", type + ";charset=utf-8");
fs.createReadStream(absFilePath).pipe(res); // 响应客户端
}
});
});
server.listen(3001); // 监听端口
3. 效果展示
http://localhost:3001/package.json
2. 通过类改写静态服务
js
let http = require('http');
let fs = require('fs').promises;
let {createReadStream} = require('fs');
let url = require('url');
let path = require('path');
let mime = require('mime');
class Server{
async handleServer(req,res){ // 创建服务
let {pathname} = url.parse(req.url);
let absFilePath = path.join(__dirname,pathname);
try{
let statObj = await fs.stat(absFilePath);
if(statObj.isDirectory()){
absFilePath = path.join(absFilePath,'index.html');
}
this.sendFile(req,res,absFilePath,statObj);
}catch(err){
console.log(err);
this.sendError(req,res);
}
}
// 发送文件响应客户端
sendFile(req,res,absFilePath,statObj){
let type = mime.getType(absFilePath);
res.setHeader('Content-Type',type+';charset=utf-8');
createReadStream(absFilePath).pipe(res);
}
sendError(req,res){ // 响应404
res.statusCode = 404;
res.end(`Not Found`);
}
// 启动服务
start(){
let server = http.createServer(this.handleServer.bind(this));
server.listen(...arguments);
}
}
let server = new Server();
server.start(3001);
3. 解决ajax跨域问题
1. cors解决跨域
a)服务端配置
js
res.setHeader("Access-Control-Allow-Origin", "http://xxx:3000"); // 允许某个域访问
res.setHeader("Access-Control-Allow-Credentials", "true"); // 允许携带cookie
res.setHeader("Access-Control-Allow-Headers", "abc"); // 允许携带的header
res.setHeader("Access-Control-Max-Age", "3600"); // 设置options的请求发送时长
'Access-Control-Allow-Origin','http://xxx:3000' // 允许某个域访问 'Access-Control-Allow-Credentials','true' // 允许携带cookie 'Access-Control-Allow-Headers','abc' // 允许携带的header 'Access-Control-Max-Age','3600' // 设置options的请求发送时长
b)客户端
js
let xhr = new XMLHttpRequest();
xhr.open('GET','http://localhost:3000/user',true);
xhr.setRequestHeader('abc','1'); // 设置请求头
xhr.onload = function(){
console.log(xhr.responseText);
}
xhr.withCredentials = true; // 设置强制携带cookie
xhr.send();
4. 压缩与解压缩处理(accept-encoding)
使用GZIP / DEFLATE 实现解压
js
var zlib = require('zlib');
var fs = require('fs');
var http = require('http');
http.createServer(function (request, response) {
var raw = fs.createReadStream('.' + request.url);
var acceptEncoding = request.headers['accept-encoding'];
if (!acceptEncoding) {
acceptEncoding = '';
}
if (acceptEncoding.match(/\bdeflate\b/)) {
response.setHeader('Content-Encoding','deflate');
raw.pipe(zlib.createDeflate()).pipe(response);
} else if (acceptEncoding.match(/\bgzip\b/)) {
response.setHeader('Content-Encoding','gzip');
raw.pipe(zlib.createGzip()).pipe(response);
} else {
raw.pipe(response);
}
}).listen(9090)
5. .多语言 (accept-language)
js
let http = require('http');
let pack = {
en: {
title: 'hello'
},
cn: {
title: '欢迎'
}
}
function request(req, res) {
let acceptLangulage = req.headers['accept-language'];
let lan = 'en';
if (acceptLangulage) {
lan = acceptLangulage.split(',').map(item => {
let values = item.split(';');
return {
name: values[0].split('-')[0],
q: isNaN(values[1]) ? 1 : parseInt(values[1])
}
}).sort((lan1, lan2) => lan1.q - lan2.q).shift().name;
}
res.end(pack[lan] ? pack[lan].title : pack['en'].title);
}
let server = http.createServer();
server.on('request', request);
server.listen(8080);