kenberkeley / vue-demo

Vue.js 示例项目 · 简易留言板。本项目拥有完善的文档说明与注释,让您快速上手 Vue.js 开发 SPA。Webpack / ES6 + Babel / Vue Router / (Vue Resource?) / (Vue Validator?) / (Vuex?) —— An Excellent Vue Starter with Best Practice / 最佳实践
https://kenberkeley.github.io/vue-demo/dist
Apache License 2.0
1.29k stars 410 forks source link

通过您的demo学习到很多,这里有一个疑问想要请教您 #8

Closed eightfeet closed 7 years ago

eightfeet commented 7 years ago

所有的spa项目都有个特性 this.$root.userData = userService.data = userSessData 通过代码去保存一些states,用vuex也一样,那么问题来了如果用户在中途刷新页面…states是会丢失的,用户又得登录,您有什么经验和建议,或者说用户刷新浏览器不丢失states(sessionStorage)。

kenberkeley commented 7 years ago

如果您有 React 开发经验,了解过服务端渲染,那么您肯定已经熟悉有关前后端的状态同步 一般是这样子操作的:后端直接在模板中吐出状态,前端使用该状态作为应用的初始状态

虽然我们的 vue-demo 并不支持服务端的渲染,但还是可以借鉴上述做法 最简单的是单机部署,/api 提供 RESTful API,/static 提供静态资源 其余访问均返回经由模板引擎渲染 npm run build 后的基页:

...
app.use('/static', express.static('./static'))

app.use('/api', [RESTful API])

app.use(function(req, res, next) {
  res.render('./dist/index.html', {
    userSession: JSON.stringify(req.session.userData) // 将用户 session 暴露到模板
  })
})
...
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Vue Demo</title>
  <meta name="viewport" content="initial-scale=1, maximum-scale=1">
  <link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>

  <div id="app"></div>

<script src="/static/jquery.min.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script>
  window.USER_SESSION = {{ userSession }}; // <--- 注入用户 session
</script>
<script src="/static/mainifest.054e05c432920807c5a6.js"></script>
<script src="/static/vendor.89695a0188eb525c7b0f.js"></script>
<script src="/static/app.9959a96192fc71dce1d6.js"></script>
</body>
</html>

无论是 cookie / localStorage / sessionStorage,均无法在保证安全性的前提下实现您的需求 当然,私建议 JSON.parse(JSON.stringify(window.USER_SESSION)) 后才使用,以断引用,防篡改

上述代码仅用于演示,生产环境下请根据实际自行编码

eightfeet commented 7 years ago

感谢您的耐心回复,明白了,也就是说安全起见,不管是通过node服务器端渲染还是RESTful Api从服务器session读取用户信息和状态,都应该交给服务端处理。非常感谢!

kenberkeley commented 7 years ago

@eightfeet 呃,其实是可以这样子来实现您的需求的:

/**
 * 检测用户是否已经登录后才挂载路由
 */
authService.checkLogin().then(userData => {
  if (userData) {
    const dataGen = App.data // data 属性是一个函数
    App.data = () => ({ ...dataGen(), userData })
  }
  router.start(App, '#app')
})
kenberkeley commented 7 years ago

Vue2 脚手架已出!!! #26