中间件

vue-srr中,使用了许多Koa2的中间件

cookie处理中间件

// 将字符串cooke转成cookie obj
module.exports = () => {
    return async (ctx, next) =>{
        const cookieHeader = ctx.headers.cookie
      if (cookieHeader) {
                const cookies = cookieHeader.split(';')

        ctx.cookie = {}
        cookies.forEach(function (item) {
          const crumbs = item.split('=')
          if (crumbs.length > 1) ctx.cookie[crumbs[0].trim()] = crumbs[1].trim()
        })
      }
        await next()
    }
}

http代理中间件 koa-better-http-proxy

/**
 * http代理中间件 匹配代理、请求重定向
 * 获取app.config.js配置文件,匹配proxy
 */
const urlUtils = require('url')
const koaHttpProxy = require('koa-better-http-proxy')
const compose = require('koa-compose')
const appConfig = require('../../../app.config')

const isProd = process.env.NODE_ENV === 'production'

/**
 * 代理处理中间件
 * @return {Function} koa middleware
 */
module.exports = () => {
    async function preProxyMiddleware(ctx, next) {
        const url = ctx.url
        //ctx.log.info(`Request '${url}'`)
        let proxyTarget
        let proxyConfig = appConfig.proxy
        // 在appConfig.proxy中寻找匹配前缀的代理
        for (const [prefix, target] of Object.entries(proxyConfig)) {
            if (url.startsWith(prefix)) {
                // 匹配替换
                ctx.url = url.replace(prefix, '')
                proxyTarget = target
                ctx._proxyTarget = proxyTarget
                //ctx.log.info(`Match to proxy: '${prefix}' => '${proxyTarget}'`)
                break
            }
        }
        if (!proxyTarget) {
            ctx.log.info('Proxy not found')
            return Promise.resolve()
        }
        //ctx.log.info(`Will be Agent to '${proxyTarget + ctx.url}'`)
        return next()
    }

  /**
   * 顺序执行async函数
   */
    return compose([
        preProxyMiddleware,
        koaHttpProxy((ctx) => { return ctx._proxyTarget }, {
            // 不解析body,不限制body大小
            parseReqBody: true,

            /**
             * 发出代理请求前的回调,更改头文件
             * @param {Object} proxyReqOpts - 代理请求选项
             * @param {ctx} ctx - koa ctx
             * @return {Promise.<*>} *
             */
            async proxyReqOptDecorator(proxyReqOpts, ctx) {
                const parsedTarget = urlUtils.parse(ctx._proxyTarget, true)
                proxyReqOpts.host = parsedTarget.hostname
                proxyReqOpts.port = parsedTarget.port
                proxyReqOpts.https = parsedTarget.protocol === 'https:'
                // 去掉Referer头,否则可能会造成CSRF问题,影响开发
                if (!isProd) {
                    delete proxyReqOpts.headers.Referer
                    delete proxyReqOpts.headers.Origin
                }

                ctx._proxyReqOpts = proxyReqOpts
                return proxyReqOpts
            },

            //发出代理请求前的回调,请求body
            async    proxyReqBodyDecorator(bodyContent, ctx) {
                const reqParams = JSON.stringify({
                    url: ctx._proxyTarget + ctx._proxyReqOpts.path,
                    method: ctx._proxyReqOpts.method,
                    cookie: ctx._proxyReqOpts.headers.cookie
                })
                ctx.log.info(`Request: param is: ${bodyContent}; and  ${reqParams}`)
                // 计时开始
                ctx._proxyStartTime = Date.now()
                return bodyContent
            },

            /**
             * 代理请求被响应后的回调
             * @param {Response} proxyRes - 代理请求选项
             * @param {Object} proxyResData - 响应数据
             * @param {ctx} ctx - koa ctx
             * @return {Promise.<*>} *
             */
            async userResDecorator(proxyRes, proxyResData, ctx) {
                const resParams = JSON.stringify({
                    cost: Date.now() - ctx._proxyStartTime + 'ms',
                    status: proxyRes.statusCode
                })
                ctx.log.info(`Response: ${resParams} res:  ${proxyResData}`)
                return proxyResData
            }
        })
    ])
}

静态资源中间件 koa-static

//设置静态资源请求目录和设置缓存
app.use(static(path.resolve(process.cwd(), 'dist'), { maxAge: 30 * 24 * 60 * 60 * 1000, gzip: true }))
app.use(static(path.resolve(process.cwd(), 'public')))

vue-server-renderer

vue-server-renderer是SSR服务器端渲染的核心模块。 server 端生成HTML的步骤:

  1. 有一个你想打包.vue文件的入口文件,就是src/entry-server.js
  2. 在webpack的配置文件中,把入口文件指向他
  3. 使用webpack对打包,会生成vue-ssr-server-bundle.json文件
  4. 使用vue-server-renderer包解析这个文件,最终渲染成HTML
Copyright ©大数据项目组 2019 all right reserved,powered by Gitbook本文档更新于: 2019-11-25 02:41

results matching ""

    No results matching ""