Skip to content

原生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

image.png

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);