Skip to content

7. Przykład [nuxt-04]: utrzymanie sesji klient–serwer

Projekt [nuxt-04] dotyczy problemu utrzymania sesji klient–serwer. Wracamy do projektu [nuxt-03], wprowadzając następujące zmiany:

  • strona [index] będzie zawierała przycisk umożliwiający zwiększenie licznika w magazynie [Vuex];
  • strona [page1] pozostaje bez zmian;
  • chcielibyśmy, aby w przypadku ręcznego wysłania żądania do serwera, serwer zwracał żądaną stronę wraz z magazynem [Vuex], którego wartość licznika odpowiadałaby ostatniej wartości, jaką miał on po stronie klienta;

Projekt [nuxt-04] został początkowo utworzony poprzez skopiowanie projektu [nuxt-03]:

Image

Zmienia się jedynie strona [index]:


<!-- strona [index] -->
<template>
  <Layout :left="true" :right="true">
    <!-- nawigacja -->
    <Navigation slot="left" />
    <!-- komunikat-->
    <template slot="right">
      <b-alert show variant="warning"> Home - value= {{ value }} </b-alert>
      <!-- przycisk -->
      <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',
  // używane komponenty
  components: {
    Layout,
    Navigation
  },
  data() {
    return {
      value: 0
    }
  },
  // cykl życia
  beforeCreate() {
    // klient i serwer
    console.log('[home beforeCreate]')
  },
  created() {
    // klient i serwer
    this.value = this.$store.state.counter
    console.log('[home created], value=', this.value)
  },
  beforeMount() {
    // tylko klient
    console.log('[home beforeMount]')
  },
  mounted() {
    // tylko klient
    console.log('[home mounted]')
  },
  // zarządzanie zdarzeniami
  methods: {
    incrementCounter() {
      console.log('incrementCounter')
      // zwiększenie licznika o 1
      this.$store.commit('increment', 1)
      // zmiana wyświetlanej wartości
      this.value = this.$store.state.counter
    }
  }
}
</script>
  • wiersz 10: dodano przycisk do zwiększania licznika rolety [Vuex];
  • wiersz 54: metoda obsługująca [clic] przycisku [Incrémenter];
  • wiersz 57: licznik rolety jest zwiększany o 1;
  • wiersz 59: wartość licznika jest przypisywana do właściwości [value], aby została wyświetlona w wierszu 8;

Uruchamiamy projekt [nuxt-04] z następującym plikiem [nuxt.config.js]:


// katalog kodu źródłowego
  srcDir: 'nuxt-04',
  // router
  router: {
    // katalog główny plików URL aplikacji
    base: '/nuxt-04/'
  },
  // serwer
  server: {
    // port usługi, domyślnie 3000
    port: 81,
    // adresy sieciowe, na których nasłuchuje, domyślnie localhost: 127.0.0.1
    // 0.0.0.0 = wszystkie adresy sieciowe komputera
    host: 'localhost'
}

Po uruchomieniu wyświetla się następująca pierwsza strona:

Image

Po kilkukrotnym kliknięciu przycisku [3] wyświetla się następująca strona:

Image

Jeśli skorzystamy z linku [3], otrzymamy następującą stronę:

Image

  • po kliknięciu [2] strona [page1] [1] prawidłowo wyświetla wartość licznika;

Teraz odświeżmy stronę za pomocą kodu [3]. Nowa strona wygląda następująco:

Image

  • na stronie [2] utracono bieżącą wartość licznika. Powrócono do jego wartości początkowej;

Wynik ten jest całkowicie zrozumiały, jeśli przyjrzymy się logom:

  • w [1] serwer ponownie wykonał funkcję [nuxtServerInit]. A oto jej treść:
/* eslint-disable no-console */
export const state = () => ({
   // licznik
  counter: 0
})

export const mutations = {
   // zwiększenie wartości licznika o jedną jednostkę [inc]
  increment(state, inc) {
    state.counter += inc
  }
}

export const actions = {
  async nuxtServerInit(store, context) {
     // kto wykonuje ten kod?
    console.log('nuxtServerInit, client=', process.client, 'serveur=', process.server)
     // czekamy na zakończenie obietnicy
    await new Promise(function(resolve, reject) {
       // zwykle mamy tu do czynienia z funkcją asynchroniczną
       // symulujemy ją, czekając jedną sekundę
      setTimeout(() => {
         // powodzenie
        resolve()
      }, 1000)
    })
     // modyfikujemy zmienną
    store.commit('increment', 53)
     // log
    console.log('nuxtServerInit commit terminé')
  }
}

W wierszu 28 przypisano licznikowi wartość 53.

Przyjrzyjmy się żądaniu HTTP wysłanemu przez przeglądarkę po odświeżeniu strony [page1]:

Image

Widać, że oprócz stron [page1] i [1] klient żąda od serwera pewnej liczby skryptów. Warto zwrócić uwagę na skrypty [pages_index, pages_page1], które są powiązane ze stronami [index, page]. Skrypty te są dostarczane przy każdym żądaniu wysyłanym do serwera, niezależnie od żądanej strony;

W przypadku [1] strona [page1] jest żądana od serwera za pomocą następującego żądania 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

Widać, że to żądanie nie przekazuje żadnych informacji do serwera. Serwer nie ma zatem możliwości poznania stanu magazynu [Vuex] po stronie klienta. Aby to było możliwe, klient musiałby przesłać mu tę informację.

W kolejnym projekcie [nuxt-05] wykorzystujemy plik cookie, aby klient mógł wysłać informacje do serwera w momencie, gdy zostanie on wywołany.