前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue服务端渲染之cookie,user-agent获取

Vue服务端渲染之cookie,user-agent获取

原创
作者头像
easonxie
修改2018-10-12 10:13:32
5.2K0
修改2018-10-12 10:13:32
举报

背景

Vue服务端渲染有个参数runInNewContext,之前我们这个参数一直设置为true,这样可以全局获取到直出的context,进而获取context里面的reqest对象,通过reqest对象拿到cookie和ua。类似下面这样。

代码语言:txt
复制
//在处理请求的server.js中,注入cookie到context

const context = {

    url: req.url,

    cookies: req.cookies

}

renderer.renderToString(context, (err, html) => {

    if (err) {

        return errorHandler(err)

    }

    res.end(html)

})

//在需要用的cookie的地方通过__VUE_SSR_CONTEXT__获取

const SSR = global.__VUE_SSR_CONTEXT__

const cookies = SSR.cookies || {}

const parseCookie = cookies => {

    let cookie = ''

    Object.keys(cookies).forEach(item => {

        cookie+= item + '=' + cookies[item] + '; '

    })

    return cookie

}

然而,runInNewContext设置为true会有比较明显的性能开销。为了优化性能,需要把runInNewContext设置为false或者once,随之而来的问题是,我们再也不能在服务端通过__VUE_SSR_CONTEXT__变量拿到请求的context对象,也就拿不到cookies和user-agent

问题:如何在runInewContext为false,或者once时候获取cookie与UA

方法一、通过store透传cookies

百度和google上面很多vue服务端渲染的实现都是这样用过store透传cookies实现的。主要的实现核心是这里,通过server-entry处理asyncData方法的时候,把context里面注入的cookie传给asyncData方法,类似这样。

代码语言:txt
复制
//server-entry.js 服务器处理asyncData的时候,透传cookie

Promise.all(matchedComponents.map(({asyncData}) => asyncData && asyncData({

    store,

    route: router.currentRoute,

    cookies: context.cookies,

    isServer: true,

    isClient: false

}))).then(() => {

    context.state = store.state

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

    resolve(app)

}).catch(reject)

这篇文章有详细的介绍再说 Vue SSR 的 Cookies 问题

方法二、通过domain挂载reqest

domain是node一个处理异步错误捕获的模块,它有一个特性,就是domain包裹的代码里面运行的时候,process.domain会指向当前这个domain,利用这个特性,我们可以把req对象挂载在domain对象里面,这样我们在服务端的时候,通过process.domain.reqest,拿到这次请求的request对象,进而拿到cookie。

实现类似这样。

代码语言:txt
复制
//server.js,创建domain包裹渲染方法

let d = domain.create();

  d.add(req);

  d.add(res);

  d.request = req;

  d.response = res;

  d.on('error', function(err) {

    res.end(500,'error')

  })



  const context = {

    title: 'Vue HN 2.0', // default title

    url: req.url,

    request:req

  }



  d.run(function() {

    renderer.renderToString(context, (err, html) => {

      if (err) {

        return handleError(err)

      }

      res.send(html)

      if (!isProd) {

        console.log(`whole request: ${Date.now() - s}ms`)

      }

    })

  })

  

  //cookie.js,封装cookie.js

  let data = {}

  Object.defineProperty(data,'cookie',{

      get:function(){

          if(process.domain){

              return process.domain.request.headers.cookie

          }else{

              return document.cookie

          }

      }

  })

  module.exports = data

各种方法对比

1.runInNewContext为ture,使用vue自带的__VUE_SSR_CONTEXT__ 来获取cookie,优点是简单粗暴,不需要太多改造,缺点是性能消耗大

2.通过透传request,性能最好的一种方式,纯透传request对象。缺点是组织代码麻烦,任何需要cookie和user-agent的地方,都需要透传req对象。

3.通过domain挂载request,有一定性能开销,但是和第一种方式一样,可以引入一个变量,直接通过这个变量获取cookie

参考资料

1.再说 Vue SSR 的 Cookies 问题

2.Node.js 异步异常的处理与domain模块解析

3.TSW路由处理模块

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 问题:如何在runInewContext为false,或者once时候获取cookie与UA
    • 方法一、通过store透传cookies
      • 方法二、通过domain挂载reqest
      • 各种方法对比
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
      http://www.vxiaotou.com