29 KiB
Δημιουργία Εφαρμογής Τραπεζικής Μέρος 2: Δημιουργία Φόρμας Σύνδεσης και Εγγραφής
Κουίζ πριν το μάθημα
Εισαγωγή
Σχεδόν σε όλες τις σύγχρονες διαδικτυακές εφαρμογές, μπορείτε να δημιουργήσετε έναν λογαριασμό για να έχετε τον δικό σας προσωπικό χώρο. Καθώς πολλοί χρήστες μπορούν να έχουν πρόσβαση σε μια εφαρμογή ταυτόχρονα, χρειάζεστε έναν μηχανισμό για να αποθηκεύετε τα προσωπικά δεδομένα κάθε χρήστη ξεχωριστά και να επιλέγετε ποια πληροφορία θα εμφανίζεται. Δεν θα καλύψουμε πώς να διαχειριστείτε την ταυτότητα του χρήστη με ασφάλεια, καθώς είναι ένα εκτενές θέμα από μόνο του, αλλά θα διασφαλίσουμε ότι κάθε χρήστης θα μπορεί να δημιουργήσει έναν (ή περισσότερους) τραπεζικούς λογαριασμούς στην εφαρμογή μας.
Σε αυτό το μέρος, θα χρησιμοποιήσουμε φόρμες HTML για να προσθέσουμε σύνδεση και εγγραφή στην εφαρμογή μας. Θα δούμε πώς να στέλνουμε δεδομένα σε έναν server API προγραμματιστικά και, τελικά, πώς να ορίσουμε βασικούς κανόνες επικύρωσης για τις εισόδους των χρηστών.
Προαπαιτούμενα
Πρέπει να έχετε ολοκληρώσει τα πρότυπα HTML και τη δρομολόγηση της εφαρμογής για αυτό το μάθημα. Πρέπει επίσης να έχετε εγκαταστήσει το Node.js και να εκτελείτε το server API τοπικά, ώστε να μπορείτε να στέλνετε δεδομένα για τη δημιουργία λογαριασμών.
Σημείωση Θα χρειαστεί να έχετε δύο τερματικά ανοιχτά ταυτόχρονα, όπως αναφέρεται παρακάτω:
- Για την κύρια τραπεζική εφαρμογή που δημιουργήσαμε στο μάθημα πρότυπα HTML και δρομολόγηση
- Για το Bank APP server API που μόλις ρυθμίσαμε παραπάνω.
Πρέπει να έχετε και τους δύο servers σε λειτουργία για να προχωρήσετε με το υπόλοιπο μάθημα. Ακούνε σε διαφορετικές θύρες (θύρα 3000
και θύρα 5000
), οπότε όλα θα λειτουργούν κανονικά.
Μπορείτε να ελέγξετε ότι ο server λειτουργεί σωστά εκτελώντας αυτήν την εντολή σε ένα τερματικό:
curl http://localhost:5000/api
# -> should return "Bank API v1.0.0" as a result
Φόρμα και στοιχεία ελέγχου
Το στοιχείο <form>
περιλαμβάνει μια ενότητα ενός εγγράφου HTML όπου ο χρήστης μπορεί να εισάγει και να υποβάλει δεδομένα με διαδραστικά στοιχεία ελέγχου. Υπάρχουν διάφορα στοιχεία διεπαφής χρήστη (UI) που μπορούν να χρησιμοποιηθούν μέσα σε μια φόρμα, με πιο συνηθισμένα τα στοιχεία <input>
και <button>
.
Υπάρχουν πολλοί διαφορετικοί τύποι του <input>
. Για παράδειγμα, για να δημιουργήσετε ένα πεδίο όπου ο χρήστης μπορεί να εισάγει το όνομα χρήστη του, μπορείτε να χρησιμοποιήσετε:
<input id="username" name="username" type="text">
Η ιδιότητα name
θα χρησιμοποιηθεί ως το όνομα της ιδιότητας όταν τα δεδομένα της φόρμας σταλούν. Η ιδιότητα id
χρησιμοποιείται για να συσχετίσει μια <label>
με το στοιχείο ελέγχου της φόρμας.
Ρίξτε μια ματιά στη λίστα με όλους τους τύπους
<input>
και άλλα στοιχεία ελέγχου φόρμας για να πάρετε μια ιδέα για όλα τα εγγενή στοιχεία UI που μπορείτε να χρησιμοποιήσετε κατά την κατασκευή της διεπαφής σας.
✅ Σημειώστε ότι το <input>
είναι ένα κενό στοιχείο στο οποίο δεν πρέπει να προσθέσετε αντίστοιχη ετικέτα κλεισίματος. Μπορείτε, ωστόσο, να χρησιμοποιήσετε τη μορφή αυτοκλεισίματος <input/>
, αλλά δεν είναι απαραίτητο.
Το στοιχείο <button>
μέσα σε μια φόρμα είναι λίγο ιδιαίτερο. Αν δεν καθορίσετε την ιδιότητα type
, θα υποβάλει αυτόματα τα δεδομένα της φόρμας στον server όταν πατηθεί. Εδώ είναι οι δυνατές τιμές για την ιδιότητα type
:
submit
: Η προεπιλογή μέσα σε μια<form>
, το κουμπί ενεργοποιεί την ενέργεια υποβολής της φόρμας.reset
: Το κουμπί επαναφέρει όλα τα στοιχεία ελέγχου της φόρμας στις αρχικές τους τιμές.button
: Δεν εκχωρεί καμία προεπιλεγμένη συμπεριφορά όταν πατηθεί το κουμπί. Μπορείτε στη συνέχεια να εκχωρήσετε προσαρμοσμένες ενέργειες χρησιμοποιώντας JavaScript.
Εργασία
Ας ξεκινήσουμε προσθέτοντας μια φόρμα στο πρότυπο login
. Θα χρειαστούμε ένα πεδίο για το όνομα χρήστη και ένα κουμπί Σύνδεσης.
<template id="login">
<h1>Bank App</h1>
<section>
<h2>Login</h2>
<form id="loginForm">
<label for="username">Username</label>
<input id="username" name="user" type="text">
<button>Login</button>
</form>
</section>
</template>
Αν παρατηρήσετε προσεκτικά, θα δείτε ότι προσθέσαμε επίσης ένα στοιχείο <label>
εδώ. Τα στοιχεία <label>
χρησιμοποιούνται για να προσθέσουν ένα όνομα στα στοιχεία UI, όπως το πεδίο ονόματος χρήστη. Οι ετικέτες είναι σημαντικές για την αναγνωσιμότητα των φορμών σας, αλλά προσφέρουν και πρόσθετα οφέλη:
- Συνδέοντας μια ετικέτα με ένα στοιχείο ελέγχου φόρμας, βοηθάτε τους χρήστες που χρησιμοποιούν τεχνολογίες υποβοήθησης (όπως αναγνώστες οθόνης) να κατανοήσουν ποια δεδομένα αναμένεται να παρέχουν.
- Μπορείτε να κάνετε κλικ στην ετικέτα για να εστιάσετε απευθείας στο συνδεδεμένο πεδίο, διευκολύνοντας την πρόσβαση σε συσκευές με οθόνη αφής.
Η προσβασιμότητα στον ιστό είναι ένα πολύ σημαντικό θέμα που συχνά παραβλέπεται. Χάρη στα σημασιολογικά στοιχεία HTML, δεν είναι δύσκολο να δημιουργήσετε προσβάσιμο περιεχόμενο αν τα χρησιμοποιήσετε σωστά. Μπορείτε να διαβάσετε περισσότερα για την προσβασιμότητα για να αποφύγετε κοινά λάθη και να γίνετε υπεύθυνος προγραμματιστής.
Τώρα θα προσθέσουμε μια δεύτερη φόρμα για την εγγραφή, ακριβώς κάτω από την προηγούμενη:
<hr/>
<h2>Register</h2>
<form id="registerForm">
<label for="user">Username</label>
<input id="user" name="user" type="text">
<label for="currency">Currency</label>
<input id="currency" name="currency" type="text" value="$">
<label for="description">Description</label>
<input id="description" name="description" type="text">
<label for="balance">Current balance</label>
<input id="balance" name="balance" type="number" value="0">
<button>Register</button>
</form>
Χρησιμοποιώντας την ιδιότητα value
, μπορούμε να ορίσουμε μια προεπιλεγμένη τιμή για ένα συγκεκριμένο πεδίο. Παρατηρήστε επίσης ότι το πεδίο για το balance
έχει τον τύπο number
. Φαίνεται διαφορετικό από τα άλλα πεδία; Δοκιμάστε να αλληλεπιδράσετε μαζί του.
✅ Μπορείτε να περιηγηθείτε και να αλληλεπιδράσετε με τις φόρμες χρησιμοποιώντας μόνο το πληκτρολόγιο; Πώς θα το κάνατε αυτό;
Υποβολή δεδομένων στον server
Τώρα που έχουμε μια λειτουργική διεπαφή χρήστη, το επόμενο βήμα είναι να στείλουμε τα δεδομένα στον server. Ας κάνουμε μια γρήγορη δοκιμή χρησιμοποιώντας τον τρέχοντα κώδικά μας: τι συμβαίνει αν κάνετε κλικ στο κουμπί Σύνδεση ή Εγγραφή;
Παρατηρήσατε την αλλαγή στην ενότητα URL του προγράμματος περιήγησης;
Η προεπιλεγμένη ενέργεια για μια <form>
είναι να υποβάλει τη φόρμα στη διεύθυνση URL του τρέχοντος server χρησιμοποιώντας τη μέθοδο GET, προσθέτοντας τα δεδομένα της φόρμας απευθείας στη διεύθυνση URL. Ωστόσο, αυτή η μέθοδος έχει ορισμένα μειονεκτήματα:
- Τα δεδομένα που αποστέλλονται είναι πολύ περιορισμένα σε μέγεθος (περίπου 2000 χαρακτήρες).
- Τα δεδομένα είναι άμεσα ορατά στη διεύθυνση URL (όχι ιδανικό για κωδικούς πρόσβασης).
- Δεν λειτουργεί με μεταφορτώσεις αρχείων.
Γι' αυτό μπορείτε να την αλλάξετε ώστε να χρησιμοποιεί τη μέθοδο POST, η οποία στέλνει τα δεδομένα της φόρμας στον server στο σώμα του αιτήματος HTTP, χωρίς κανέναν από τους προηγούμενους περιορισμούς.
Ενώ η POST είναι η πιο συχνά χρησιμοποιούμενη μέθοδος για την αποστολή δεδομένων, σε ορισμένα συγκεκριμένα σενάρια είναι προτιμότερο να χρησιμοποιείται η μέθοδος GET, όπως για την υλοποίηση ενός πεδίου αναζήτησης.
Εργασία
Προσθέστε τις ιδιότητες action
και method
στη φόρμα εγγραφής:
<form id="registerForm" action="//localhost:5000/api/accounts" method="POST">
Δοκιμάστε τώρα να εγγραφείτε με το όνομά σας. Μετά το πάτημα του κουμπιού Εγγραφή, θα πρέπει να δείτε κάτι σαν αυτό:
Αν όλα πάνε καλά, ο server θα απαντήσει στο αίτημά σας με μια JSON απόκριση που περιέχει τα δεδομένα του λογαριασμού που δημιουργήθηκε.
✅ Δοκιμάστε να εγγραφείτε ξανά με το ίδιο όνομα. Τι συμβαίνει;
Υποβολή δεδομένων χωρίς ανανέωση της σελίδας
Όπως πιθανώς παρατηρήσατε, υπάρχει ένα μικρό πρόβλημα με την προσέγγιση που μόλις χρησιμοποιήσαμε: κατά την υποβολή της φόρμας, βγαίνουμε από την εφαρμογή μας και το πρόγραμμα περιήγησης ανακατευθύνεται στη διεύθυνση URL του server. Προσπαθούμε να αποφύγουμε όλες τις ανανεώσεις σελίδων με την εφαρμογή μας, καθώς δημιουργούμε μια Εφαρμογή Μίας Σελίδας (SPA).
Για να στείλουμε τα δεδομένα της φόρμας στον server χωρίς να αναγκάσουμε την ανανέωση της σελίδας, πρέπει να χρησιμοποιήσουμε κώδικα JavaScript. Αντί να βάζετε μια διεύθυνση URL στην ιδιότητα action
ενός στοιχείου <form>
, μπορείτε να χρησιμοποιήσετε οποιονδήποτε κώδικα JavaScript που ξεκινά με τη συμβολοσειρά javascript:
για να εκτελέσετε μια προσαρμοσμένη ενέργεια. Χρησιμοποιώντας αυτό, σημαίνει επίσης ότι θα πρέπει να υλοποιήσετε ορισμένες εργασίες που προηγουμένως γίνονταν αυτόματα από το πρόγραμμα περιήγησης:
- Ανάκτηση των δεδομένων της φόρμας
- Μετατροπή και κωδικοποίηση των δεδομένων της φόρμας σε κατάλληλη μορφή
- Δημιουργία του αιτήματος HTTP και αποστολή του στον server
Εργασία
Αντικαταστήστε την ιδιότητα action
της φόρμας εγγραφής με:
<form id="registerForm" action="javascript:register()">
Ανοίξτε το app.js
και προσθέστε μια νέα συνάρτηση με όνομα register
:
function register() {
const registerForm = document.getElementById('registerForm');
const formData = new FormData(registerForm);
const data = Object.fromEntries(formData);
const jsonData = JSON.stringify(data);
}
Εδώ ανακτούμε το στοιχείο της φόρμας χρησιμοποιώντας το getElementById()
και χρησιμοποιούμε τον βοηθό FormData
για να εξαγάγουμε τις τιμές από τα στοιχεία ελέγχου της φόρμας ως ένα σύνολο ζευγών κλειδιού/τιμής. Στη συνέχεια, μετατρέπουμε τα δεδομένα σε ένα κανονικό αντικείμενο χρησιμοποιώντας το Object.fromEntries()
και τελικά τα σειριοποιούμε σε JSON, μια μορφή που χρησιμοποιείται συνήθως για την ανταλλαγή δεδομένων στον ιστό.
Τα δεδομένα είναι τώρα έτοιμα να σταλούν στον server. Δημιουργήστε μια νέα συνάρτηση με όνομα createAccount
:
async function createAccount(account) {
try {
const response = await fetch('//localhost:5000/api/accounts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: account
});
return await response.json();
} catch (error) {
return { error: error.message || 'Unknown error' };
}
}
Τι κάνει αυτή η συνάρτηση; Πρώτα, παρατηρήστε τη λέξη-κλειδί async
εδώ. Αυτό σημαίνει ότι η συνάρτηση περιέχει κώδικα που θα εκτελεστεί ασύγχρονα. Όταν χρησιμοποιείται μαζί με τη λέξη-κλειδί await
, επιτρέπει την αναμονή για την εκτέλεση ασύγχρονου κώδικα - όπως η αναμονή για την απόκριση του server εδώ - πριν συνεχίσει.
Εδώ είναι ένα γρήγορο βίντεο για τη χρήση του async/await
:
🎥 Κάντε κλικ στην εικόνα παραπάνω για ένα βίντεο σχετικά με το async/await.
Χρησιμοποιούμε το API fetch()
για να στείλουμε δεδομένα JSON στον server. Αυτή η μέθοδος παίρνει 2 παραμέτρους:
- Τη διεύθυνση URL του server, οπότε βάζουμε ξανά το
//localhost:5000/api/accounts
εδώ. - Τις ρυθμίσεις του αιτήματος. Εκεί ορίζουμε τη μέθοδο σε
POST
και παρέχουμε τοbody
για το αίτημα. Καθώς στέλνουμε δεδομένα JSON στον server, πρέπει επίσης να ορίσουμε την κεφαλίδαContent-Type
σεapplication/json
, ώστε ο server να γνωρίζει πώς να ερμηνεύσει το περιεχόμενο.
Καθώς ο server θα απαντήσει στο αίτημα με JSON, μπορούμε να χρησιμοποιήσουμε το await response.json()
για να αναλύσουμε το περιεχόμενο JSON και να επιστρέψουμε το αποτέλεσμα ως αντικείμενο. Σημειώστε ότι αυτή η μέθοδος είναι ασύγχρονη, οπότε χρησιμοποιούμε τη λέξη-κλειδί await
εδώ πριν επιστρέψουμε για να διασφαλίσουμε ότι τυχόν σφάλματα κατά την ανάλυση θα πιαστούν επίσης.
Τώρα προσθέστε λίγο κώδικα στη συνάρτηση register
για να καλέσετε το createAccount()
:
const result = await createAccount(jsonData);
Επειδή χρησιμοποιούμε τη λέξη-κλειδί await
εδώ, πρέπει να προσθέσουμε τη λέξη-κλειδί async
πριν από τη συνάρτηση register:
async function register() {
Τέλος, ας προσθέσουμε μερικά logs για να ελέγξουμε το αποτέλεσμα. Η τελική συνάρτηση θα πρέπει να μοιάζει με αυτή:
async function register() {
const registerForm = document.getElementById('registerForm');
const formData = new FormData(registerForm);
const jsonData = JSON.stringify(Object.fromEntries(formData));
const result = await createAccount(jsonData);
if (result.error) {
return console.log('An error occurred:', result.error);
}
console.log('Account created!', result);
}
Ήταν λίγο μακρύ, αλλά τα καταφέραμε! Αν ανοίξετε τα εργαλεία προγραμματιστή του προγράμματος περιήγησης και δοκιμάσετε να εγγραφείτε σε έναν νέο λογαριασμό, δεν θα δείτε καμία αλλαγή στη σελίδα, αλλά ένα μήνυμα θα εμφανιστεί στην κονσόλα επιβεβαιώνοντας ότι όλα λειτουργούν.
✅ Πιστεύετε ότι τα δεδομένα αποστέλλονται
Συμβουλή: μπορείτε να προσαρμόσετε την εμφάνιση των στοιχείων ελέγχου της φόρμας σας ανάλογα με το αν είναι έγκυρα ή όχι, χρησιμοποιώντας τις ψευδοκλάσεις CSS
:valid
και:invalid
.
Εργασία
Υπάρχουν 2 απαιτούμενα πεδία για τη δημιουργία ενός έγκυρου νέου λογαριασμού: το όνομα χρήστη και το νόμισμα, ενώ τα υπόλοιπα πεδία είναι προαιρετικά. Ενημερώστε το HTML της φόρμας, χρησιμοποιώντας τόσο το χαρακτηριστικό required
όσο και το κείμενο στην ετικέτα του πεδίου ώστε να:
<label for="user">Username (required)</label>
<input id="user" name="user" type="text" required>
...
<label for="currency">Currency (required)</label>
<input id="currency" name="currency" type="text" value="$" required>
Αν και αυτή η συγκεκριμένη υλοποίηση του διακομιστή δεν επιβάλλει συγκεκριμένα όρια στο μέγιστο μήκος των πεδίων, είναι πάντα καλή πρακτική να ορίζονται λογικά όρια για οποιαδήποτε εισαγωγή κειμένου από τον χρήστη.
Προσθέστε ένα χαρακτηριστικό maxlength
στα πεδία κειμένου:
<input id="user" name="user" type="text" maxlength="20" required>
...
<input id="currency" name="currency" type="text" value="$" maxlength="5" required>
...
<input id="description" name="description" type="text" maxlength="100">
Τώρα, αν πατήσετε το κουμπί Εγγραφή και κάποιο πεδίο δεν πληροί έναν από τους κανόνες επικύρωσης που ορίσαμε, θα δείτε κάτι σαν αυτό:
Η επικύρωση που πραγματοποιείται πριν σταλούν δεδομένα στον διακομιστή ονομάζεται επικύρωση από την πλευρά του πελάτη (client-side validation). Ωστόσο, σημειώστε ότι δεν είναι πάντα δυνατό να πραγματοποιηθούν όλοι οι έλεγχοι χωρίς την αποστολή δεδομένων. Για παράδειγμα, δεν μπορούμε να ελέγξουμε εδώ αν υπάρχει ήδη λογαριασμός με το ίδιο όνομα χρήστη χωρίς να στείλουμε ένα αίτημα στον διακομιστή. Η πρόσθετη επικύρωση που πραγματοποιείται στον διακομιστή ονομάζεται επικύρωση από την πλευρά του διακομιστή (server-side validation).
Συνήθως, και οι δύο μέθοδοι πρέπει να υλοποιούνται. Ενώ η χρήση της επικύρωσης από την πλευρά του πελάτη βελτιώνει την εμπειρία του χρήστη παρέχοντας άμεση ανατροφοδότηση, η επικύρωση από την πλευρά του διακομιστή είναι κρίσιμη για να διασφαλιστεί ότι τα δεδομένα του χρήστη που επεξεργάζεστε είναι έγκυρα και ασφαλή.
🚀 Πρόκληση
Εμφανίστε ένα μήνυμα σφάλματος στο HTML αν ο χρήστης υπάρχει ήδη.
Ακολουθεί ένα παράδειγμα για το πώς μπορεί να μοιάζει η τελική σελίδα σύνδεσης μετά από λίγη μορφοποίηση:
Κουίζ μετά το μάθημα
Ανασκόπηση & Αυτομελέτη
Οι προγραμματιστές έχουν γίνει πολύ δημιουργικοί στις προσπάθειές τους για τη δημιουργία φορμών, ειδικά όσον αφορά τις στρατηγικές επικύρωσης. Μάθετε για διαφορετικές ροές φορμών εξετάζοντας το CodePen. Μπορείτε να βρείτε ενδιαφέρουσες και εμπνευσμένες φόρμες;
Εργασία
Διαμορφώστε την εφαρμογή της τράπεζάς σας
Αποποίηση Ευθύνης:
Αυτό το έγγραφο έχει μεταφραστεί χρησιμοποιώντας την υπηρεσία αυτόματης μετάφρασης Co-op Translator. Παρόλο που καταβάλλουμε κάθε προσπάθεια για ακρίβεια, παρακαλούμε να έχετε υπόψη ότι οι αυτόματες μεταφράσεις ενδέχεται να περιέχουν λάθη ή ανακρίβειες. Το πρωτότυπο έγγραφο στη μητρική του γλώσσα θα πρέπει να θεωρείται η αυθεντική πηγή. Για κρίσιμες πληροφορίες, συνιστάται επαγγελματική ανθρώπινη μετάφραση. Δεν φέρουμε ευθύνη για τυχόν παρεξηγήσεις ή εσφαλμένες ερμηνείες που προκύπτουν από τη χρήση αυτής της μετάφρασης.