Exemple [nuxt-04] : maintien d’une session client / serveur¶
Le projet [nuxt-04] aborde le problème du maintien d’une session client / serveur. On reprend le projet [nuxt-03] avec les modifications suivantes :
- la page [index] aura un bouton qui permettra d’incrémenter le compteur du store [Vuex] ;
- la page [page1] reste inchangée ;
- on voudrait que lorsqu’une page est demandée à la main au serveur, celui-ci renvoie la page demandée avec un store [Vuex] qui aurait pour valeur de compteur, la dernière valeur que celui-ci avait côté client ;
Le projet [nuxt-04] est initialement créé par recopie du projet [nuxt-03] :
Seule la page [index] change :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | <!-- page [index] -->
<template>
<Layout :left="true" :right="true">
<!-- navigation -->
<Navigation slot="left" />
<!-- message-->
<template slot="right">
<b-alert show variant="warning"> Home - value= {{ value }} </b-alert>
<!-- bouton -->
<b-button @click="incrementCounter" class="ml-3" variant="primary">Incrémenter</b-button>
</template>
</Layout>
</template>
<script>
/* eslint-disable no-undef */
/* eslint-disable no-console */
/* eslint-disable nuxt/no-env-in-hooks */
import Layout from '@/components/layout'
import Navigation from '@/components/navigation'
export default {
name: 'Home',
// composants utilisés
components: {
Layout,
Navigation
},
data() {
return {
value: 0
}
},
// cycle de vie
beforeCreate() {
// client et serveur
console.log('[home beforeCreate]')
},
created() {
// client et serveur
this.value = this.$store.state.counter
console.log('[home created], value=', this.value)
},
beforeMount() {
// client seulement
console.log('[home beforeMount]')
},
mounted() {
// client seulement
console.log('[home mounted]')
},
// gestion des évts
methods: {
incrementCounter() {
console.log('incrementCounter')
// incrément du compteur de 1
this.$store.commit('increment', 1)
// chgt de la valeur affichée
this.value = this.$store.state.counter
}
}
}
</script>
|
- ligne 10 : on a ajouté un bouton pour incrémenter le compteur du store [Vuex] ;
- ligne 54 : la méthode qui gère le [clic] sur le bouton [Incrémenter] ;
- ligne 57 : le compteur du store est incrémenté de 1 ;
- ligne 59 : la valeur du compteur est affectée à la propriété [value] afin qu’elle soit affichée par la ligne 8 ;
On exécute le projet [nuxt-04] avec le fichier [nuxt.config.js] suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // répertoire du code source
srcDir: 'nuxt-04',
// routeur
router: {
// racine des URL de l'application
base: '/nuxt-04/'
},
// serveur
server: {
// port de service, 3000 par défaut
port: 81,
// adresses réseau écoutées, par défaut localhost : 127.0.0.1
// 0.0.0.0 = toutes les adresses réseau de la machine
host: 'localhost'
}
|
A l’exécution la première page affichée est la suivante :
En utilisant plusieurs fois le bouton [3], on a la nouvelle page suivante :
Si on utilise le lien [3], on a la page suivante :
- en [2], la page [page1] [1] affiche bien la valeur du compteur ;
Maintenant, rafraîchissons la page avec [3]. La nouvelle page est la suivante :
- en [2], on a perdu la valeur courante du compteur. On est revenu à sa valeur initiale ;
Ce résultat est tout a fait compréhensible si on regarde les logs :
- en [1], le serveur a réexécuté la fonction [nuxtServerInit]. Or celle-ci est la suivante :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* eslint-disable no-console */
export const state = () => ({
// compteut
counter: 0
})
export const mutations = {
// incrémentation du compteur d'une valeur [inc]
increment(state, inc) {
state.counter += inc
}
}
export const actions = {
async nuxtServerInit(store, context) {
// qui exécute ce code ?
console.log('nuxtServerInit, client=', process.client, 'serveur=', process.server)
// on attend la fin d'une promesse
await new Promise(function(resolve, reject) {
// on a normalement ici une fonction asynchrone
// on la simule avec une attente d'une seconde
setTimeout(() => {
// succès
resolve()
}, 1000)
})
// on modifie le store
store.commit('increment', 53)
// log
console.log('nuxtServerInit commit terminé')
}
}
|
La ligne 28 affecte la valeur 53 au compteur.
Examinons la requête HTTP faite par le navigateur lorsqu’on a rafraîchi la page [page1] :
On voit qu’outre la page [page1] [1], le client demande un certain nombre de scripts au serveur. On notera les scripts [pages_index, pages_page1] qui sont les scripts associés aux pages [index, page]. Ces scripts sont fournis à chaque requête au serveur quelque soit la page demandée ;
En [1], la page [page1] est demandée au serveur avec la requête HTTP suivante :
1 2 3 4 5 6 7 8 9 10 11 | GET http://localhost:81/nuxt-04/page1
Host: localhost:81
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
|
On voit que cette requête ne transmet aucune information au serveur. Celui-ci n’a donc aucun moyen de connaître l’état du store [Vuex] côté client. Il aurait fallu pour cela que le client lui envoie cette information.
Dans le projet suivant [nuxt-05] nous utilisons un cookie pour que le client puisse envoyer de l’information au serveur lorsque celui-ci est sollicité.