zhaobinglong / myBlog

https://zhaobinglong.github.io/myBlog/
MIT License
7 stars 0 forks source link

基于express框架的项目架构 #72

Open zhaobinglong opened 3 years ago

zhaobinglong commented 3 years ago

express框架

express VS koa

基于express实现mvc项目

app.set("view engine","ejs")
app.get("/",function(req,res){
    res.render("from")
});
//post提交表单
app.post("/",function(req,res){
    res.send("成功")
})

模板引擎

helmet规避web漏洞

// Load required modules
var express = require('express');
var helmet = require('helmet');

// Create our Express application
var app = express();

// Implement CSP with Helmet
app.use(helmet.csp({
  defaultSrc: ["'self'"],
  scriptSrc: ['*.google-analytics.com'],
  styleSrc: ["'unsafe-inline'"],
  imgSrc: ['*.google-analytics.com'],
  connectSrc: ["'none'"],
  fontSrc: [],
  objectSrc: [],
  mediaSrc: [],
  frameSrc: []
}));

// Simple endpoint
app.get('/', function(req, res) {
  res.send('Time to secure your application...');
});

// Start the server
app.listen(3000);

express接口跨域

app.use('*', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers",'Content-Type,Content-Length, Authorization, Accept,X-Requested-With');
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By",'3.2.1')
    next();
});

日志处理

参考

https://blog.csdn.net/disappearedgod/article/details/50457421

zhaobinglong commented 3 years ago

占位

zhaobinglong commented 3 years ago

理解中间件app.use

中间件函数是可以访问请求对象 (req),响应对象(res)以及next应用程序请求 - 响应周期中的函数的函数。该next功能是Express路由器中的一个功能,当被调用时,它将执行当前中间件之后的中间件。

var express = require('express');
var app = express();
app.listen(3000, function () {
    console.log('listen 3000...');
});
app.use(middlewareA);
app.use(middlewareB);
app.use(middlewareC);

app.use的原理,就是每调用一次use,就把传进来的函数扔到express内部维护的一个函数数组中去

中间件代码模型

/**
 * 仿express实现中间件机制
 *
 * @return {app}
 */
function express() {

    var funcs = []; // 待执行的函数数组

    var app = function (req, res) {
        var i = 0;

        function next() {
            var task = funcs[i++];  // 取出函数数组里的下一个函数
            if (!task) {    // 如果函数不存在,return
                return;
            }
            task(req, res, next);   // 否则,执行下一个函数
        }

        next();
    }

    /**
     * use方法就是把函数添加到函数数组中
     * @param task
     */
    app.use = function (task) {
        funcs.push(task);
    }

    return app;    // 返回实例
}

中间件功能可以执行以下任务:

如果当前的中间件函数没有结束请求 - 响应周期,则必须调用next()以将控制传递给下一个中间件函数。否则,请求将被挂起。 image

中间件分类

中间件执行顺序

按照定义的顺序执行

zhaobinglong commented 3 years ago

自定义中间件函数

中间件的本质是一个函数,在响应发送之前对请求进行一些操作。这个函数有些不太一样,它还有一个next参数,而这个next也是一个函数,它表示函数数组中的下一个函数。express内部维护一个函数数组,这个函数数组表示在发出响应之前要执行的所有函数,也就是中间件数组

var myLogger = function (req, res, next) {
  console.log('LOGGED')
  next()
}

app.use(myLogger)

注意上面的调用next()。调用此函数会调用应用程序中的下一个中间件函数。该next()函数不是Node.js或Express API的一部分,而是传递给中间件函数的第三个参数。该next()函数可以命名为任何东西,但按照惯例,它总是被命名为“next”。为避免混淆,请始终使用此约定。

var requestTime = function (req, res, next) {
  req.requestTime = Date.now()
  next()
}

app.use(requestTime)

app.get('/', function (req, res) {
  var responseText = 'Hello World!<br>'
  responseText += '<small>Requested at: ' + req.requestTime + '</small>'
  res.send(responseText)
})
zhaobinglong commented 3 years ago

中间件执行位置

全局中间价

var app = express()
// 只要用户访问项目,就会执行
app.use(function (req, res, next) {
  console.log('Time:', Date.now())
  next()
})
...

路由级中间件

// 只在指定路径上执行
app.use('/user/:id', function (req, res, next) {
  console.log('Request Type:', req.method)
  next()
})

官方中间件

https://github.com/senchalabs/connect#middleware

第三方中间件

zhaobinglong commented 3 years ago

express项目性能优化

利用compression实现压缩

var compression = require('compression');
app.use(compression());
zhaobinglong commented 3 years ago

利用pm2管理应用

// 安装
npm  install -g pm2

// 将应用启动四个进程,有几个cpu,就启动几个
pm2 start app.js -i 4
pm2 list

获取服务器中某个应用的详细信息

pm2 show id

查看服务器当前状态信息

pm2 l

追踪进程消耗的资源 pm2 monit

实时集中log处理 pm2 logs

快速恢复(硬重启 hard reset) pm2 dump pm2 kill pm2 resurect

调试api pm2 web

查看应用端口

api.xxx.com

任务频繁重启

image

pm2配置文件

// 自动生成配置文件
pm2 init

pm2监听文件变化,同时忽略指定文件夹

pm2 start app.js --watch
zhaobinglong commented 3 years ago

nginx 反向代理node应用

在nginx配置文件种的http节点下:

server {
    listen 80;
    server_name  api.xxx.com;
    index index.html index.htm index.php default.html default.htm default.php;
    location /{
        proxy_set_header X_Real_IP $remote_addr;
        proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:3000; // 反向代理的地址
        proxy_redirect off;
    }
}

// 重启nginx
lnmp nginx restart

// 浏览器输入api.xxx.com, nginx代理到http://localhost:3000/