框架背景:開發框架採用vue,須要更好的SEO,更快的內容到達時間,從瀏覽器看不到對服務器的請求接口,選用開箱即用的nuxtjs。前端
問題背景:1. 先後分離,需前端存儲token及登陸後的用戶信息;vue
2. vuex存儲數據,當頁面刷新時,數據會丟失;ios
3. 鑑於第一點,採用localstorage或sessionStorage存儲數據,頁面刷新,數據不會丟失,BUT,localStorage or sessionStorage 是瀏覽器的對象,服務端渲染頁面時,會提示undefined(畢竟服務器是沒有這兩個對象的);vuex
解決措施: 採用session (原本採用的是express-session,但此模塊爲開發環境設計,在生產環境會警告可能內存泄漏,故採用cookie-session)express
以下:npm
1. 在項目根目錄下新建server.js:json
代碼以下: axios
const {Nuxt, Builder} = require('nuxt'); const bodyParser = require('body-parser'); const session = require('cookie-session'); const app = require('express')(); const router = require('express').Router() // 用來封裝req.body app.use(bodyParser.json()); //session 來建立req.session app.use(session({ secret: 'gjr', resave: false, saveUninitialized: false, cookie: {maxAge: 2*24*60*60*1000} })); // 發起post /api/login 請求完成企業用戶登陸,並添加該用戶信息到req.session.firmUser router.post('/api/login', (req, res) => { // 收到express服務請求,進行以下處理 if (req.body.token) { req.session.firmUser = { authStatus:req.body.authStatus, id: req.body.id, loginName: req.body.loginName, token: req.body.token} return res.json({ authStatus:req.body.authStatus, id: req.body.id, loginName: req.body.loginName, token: req.body.token}) } res.status(401).json({message: '401 Bad credentials'}) }); // 發起post /api/logout 請求註銷當前企業用戶,並從req.session中移除 router.post('/api/logout', (req, res) => { delete req.session.firmUser; res.json({ok: true}) }); app.use(router); // 咱們用這些選項初始化 nuxt.js; const isProd = process.env.NODE_ENV === 'production' let config = require('../nuxt.config') config.dev = !isProd; const nuxt = new Nuxt(config); app.use(nuxt.render) // 生產模式不須要build if(!isProd) { const builder = new Builder(nuxt) builder.build() .catch((error) => { console.log(error) process.exit(1) }) } app.listen(8081, function () { console.log('Server is listening on http://localhost:8081') })
需先安裝:api
npm install express cookie-session body-parser --save
2. 在store的user.js中:瀏覽器
import axios from 'axios' export default { state: { firmUser: null, clientUser: null, proUser: null }, getters: { firmUser: state => state.firmUser, clientUser: state => state.clientUser, proUser: state => state.proUser }, mutations: { SET_FIRMUSER: (state, user) => { state.firmUser = user; } }, actions: { nuxtServerInit({commit}, {req}) { // 將本地服務端數據發送給瀏覽器 if (req.session && req.session.firmUser) { commit('SET_FIRMUSER', req.session.firmUser) } }, async firmLogin({commit}, {authStatus, id, loginName, token}) { try { const {data} = await axios.post('/api/login', {authStatus, id, loginName, token}) // 向express服務發起請求 commit('SET_FIRMUSER', data) } catch (error) { if (error.response && error.response.status === 401) { throw new Error('bad error') } throw error } }, async firmLogout({commit}) { await axios.post('/api/logout') commit('SET_FIRMUSER', null) } } }
3. 在login.vue中:
login() { this.$refs.form.validate(valid => { if (valid) { this.$fetch.post('/companyUser/login', this.form).then(res => { // 向後臺請求 this.$store.dispatch('firmLogin', res.data).then(() => { // 調用store的方法 this.$router.push('/firm/center'); }); }) } }) }
以上,token信息或者用戶信息就能夠在本地服務及瀏覽器中共享了,且刷新頁面不會丟失。
下一節講啓動服務,以及在服務器上怎麼用pm2部署nuxtjs程序。