Skip to content

7. Exemplo [nuxt-04]: manutenção de uma sessão cliente/servidor

O projeto [nuxt-04] aborda o problema da manutenção de uma sessão cliente/servidor. Retomamos o projeto [nuxt-03] com as seguintes alterações:

  • a página [index] terá um botão que permitirá incrementar o contador do store [Vuex];
  • a página [page1] permanece inalterada;
  • gostaríamos que, quando uma página fosse solicitada manualmente ao servidor, este devolvesse a página solicitada com um armazenamento [Vuex] cujo valor do contador fosse o último valor que este tinha do lado do cliente;

O projeto [nuxt-04] é inicialmente criado por cópia do projeto [nuxt-03]:

Image

Apenas a página [index] é alterada:


<!-- página [index] -->
<template>
  <Layout :left="true" :right="true">
    <!-- navegação -->
    <Navigation slot="left" />
    <!-- mensagem-->
    <template slot="right">
      <b-alert show variant="warning"> Home - value= {{ value }} </b-alert>
      <!-- botão -->
      <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',
  // componentes utilizados
  components: {
    Layout,
    Navigation
  },
  data() {
    return {
      value: 0
    }
  },
  // ciclo de vida
  beforeCreate() {
    // cliente e servidor
    console.log('[home beforeCreate]')
  },
  created() {
    // cliente e servidor
    this.value = this.$store.state.counter
    console.log('[home created], value=', this.value)
  },
  beforeMount() {
    // apenas cliente
    console.log('[home beforeMount]')
  },
  mounted() {
    // apenas cliente
    console.log('[home mounted]')
  },
  // gestão de eventos
  methods: {
    incrementCounter() {
      console.log('incrementCounter')
      // incremento do contador em 1
      this.$store.commit('increment', 1)
      // alteração do valor apresentado
      this.value = this.$store.state.counter
    }
  }
}
</script>
  • linha 10: foi adicionado um botão para incrementar o contador da loja [Vuex];
  • linha 54: o método que gere o [clic] no botão [Incrémenter];
  • linha 57: o contador da persiana é incrementado em 1;
  • linha 59: o valor do contador é atribuído à propriedade [value] para que seja exibido na linha 8;

Executa-se o projeto [nuxt-04] com o seguinte ficheiro [nuxt.config.js]:


// diretório do código-fonte
  srcDir: 'nuxt-04',
  // router
  router: {
    // raiz dos URL da aplicação
    base: '/nuxt-04/'
  },
  // servidor
  server: {
    // porta de serviço, 3000 por predefinição
    port: 81,
    // endereços de rede em escuta, por predefinição localhost: 127.0.0.1
    // 0.0.0.0 = todos os endereços de rede da máquina
    host: 'localhost'
}

Ao executar, a primeira página apresentada é a seguinte:

Image

Ao clicar várias vezes no botão [3], obtém-se a seguinte nova página:

Image

Se utilizarmos o link [3], obtemos a seguinte página:

Image

  • em [2], a página [page1] [1] apresenta corretamente o valor do contador;

Agora, atualizemos a página com [3]. A nova página é a seguinte:

Image

  • em [2], perdemos o valor atual do contador. Voltámos ao seu valor inicial;

Este resultado é perfeitamente compreensível se analisarmos os registos:

  • em [1], o servidor voltou a executar a função [nuxtServerInit]. Ora, esta é a seguinte:
/* eslint-disable no-console */
export const state = () => ({
   // contador
  counter: 0
})

export const mutations = {
   // incremento do contador em um valor [inc]
  increment(state, inc) {
    state.counter += inc
  }
}

export const actions = {
  async nuxtServerInit(store, context) {
     // quem executa este código?
    console.log('nuxtServerInit, client=', process.client, 'serveur=', process.server)
     // aguardamos o fim de uma promessa
    await new Promise(function(resolve, reject) {
       // normalmente, aqui temos uma função assíncrona
       // simulamo-la com uma espera de um segundo
      setTimeout(() => {
         // sucesso
        resolve()
      }, 1000)
    })
     // altera-se o store
    store.commit('increment', 53)
     // registo
    console.log('nuxtServerInit commit terminé')
  }
}

A linha 28 atribui o valor 53 ao contador.

Analisemos a solicitação HTTP efetuada pelo navegador quando atualizámos a página [page1]:

Image

Vemos que, além das páginas [page1] e [1], o cliente solicita uma série de scripts ao servidor. Destacam-se os scripts [pages_index, pages_page1], que são os scripts associados às páginas [index, page]. Estes scripts são fornecidos em cada pedido ao servidor, independentemente da página solicitada;

Em [1], a página [page1] é solicitada ao servidor com a seguinte solicitação HTTP:

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

Vê-se que esta solicitação não transmite qualquer informação ao servidor. Por conseguinte, este não tem qualquer forma de conhecer o estado da loja [Vuex] do lado do cliente. Para tal, teria sido necessário que o cliente lhe enviasse essa informação.

No projeto seguinte, [nuxt-05], utilizamos um cookie para que o cliente possa enviar informações ao servidor quando este é solicitado.