构建功能丰富的 Web 客户端:认证、添加与删除功能实现
1. 开启拓展之旅
恭喜你,已经拥有一个可运行的 Web 客户端了!不过,这还不是终点。接下来,你将为这个客户端添加更多强大的功能,具体如下:
- 添加认证功能,保障用户账户安全。
- 赋予账户添加新表情符号条目的能力。
- 支持从账户中删除表情符号条目。
Stencil 是一个强大的模板框架,你可以在其 GitHub 仓库 中深入了解它。
2. 完善 Web 布局
首先,你要通过编写 HTML 来布局用户管理所需的工具。这里可以借助一个简单的 JS 弹出库,并编写一些 jQuery 代码将所有适当的操作与之关联起来。
需要提醒的是,你并非必须使用 Xcode 来编辑文件,像 Visual Studio Code 等编辑器都是不错的选择。
具体操作步骤如下:
1. 打开项目,待 Xcode 解析完依赖后,构建并运行服务器。
2. 在浏览器中打开两个标签页,分别访问以下地址:
- http://localhost:8080/openapi/ui
- http://localhost:8080/client
3. 利用 Kitura OpenAPI UI 为不同用户添加一两个日记条目。例如,点击 POST /user 路由,添加以下两个用户:
{
"id": "bill",
"password": "excellent"
}
{
"id": "ted",
"password": "adventure"
}
- 为每个用户添加一两个日记条目,确保日期以大数字形式表示,如:
{
"emoji":"( ",
"date": 563725805.57661498
}
- 在
Sources/Application/Routes/WebClientRoutes.swift文件中设置断点,检查webEntries数组,确保有两个条目属于不同用户。 - 打开
Views/home.stencil文件,在<div class='menu-container'>下方添加以下代码:
<div id="user-info-popup" style="align-self: auto;">
<input id="username-field" placeholder="username">
<br>
<input id="password-field" type="password"
placeholder="password">
<br>
<button id="cancel-signup-button"
onclick="cancelButtonTapped()">Cancel</button>
<button id="signup-button" onclick="createUser()">
Sign Up
</button>
<button id="login-button" onclick="login()">Login</button>
<button id="logout-button" onClick="logout()">Logout</button>
</div>
- 刷新浏览器,你会在左上角看到新添加的元素。
- 滚动到文件底部,在导入 JavaScript 文件的代码块末尾添加以下代码:
<script src="https://cdn.rawgit.com/vast-engineering/jquery-popup-overlay/1.7.13/jquery.popupoverlay.js"></script>
- 在第一个没有显式调用 URL 导入的
<script>标签下方,添加以下代码:
$(document).ready(() => {
$('#user-info-popup').popup({
color: '#FFF',
opacity: 0.9
})
})
- 刷新浏览器,登录窗口会暂时隐藏。
- 找到
home.stencil文件中类似以下的代码块:
<div class="wrapper">
<div class='title'><h1>& EmojiJournal & </h1></div>
</div>
将其替换为:
<div class="wrapper"
style="display: grid;grid-template-columns: 1fr 1fr 1fr;">
<div id="logged-in" style=
"display:flex;margin:0;align-items:center;color:white;">
</div>
<div class='title'>
<h1>& EmojiJournal & </h1>
</div>
<div class="wrapper"
style="display: flex;align-items: center;margin: 0;">
<div class="title-login" onclick="signupClicked()"
style="margin-left: auto;color: white;">
User Management
</div>
</div>
</div>
这里有几点需要注意:
- 可以使用内联样式规则覆盖 index.css 文件中的样式,但不要过度使用。
- HTML 组件可以是 div ,并可分配 class 和 onClick 等属性。 class 便于在 jQuery 中引用 HTML 文档, onClick 用于指定点击元素时要运行的 JS 函数。
- 代码中多次使用的 flex 与 Flexbox 布局库相关,你可以在 这里 了解更多。
刷新浏览器,你会看到网页顶部出现一个白色的 “User Management” 链接。点击它,目前可能没有反应,因为还需要定义 signupClicked 函数。在文件底部的 <script> 块中添加以下代码:
function signupClicked() {
$('#user-info-popup').popup('show')
}
3. 让网页按钮生效
现在,你要为新添加的对话框添加关闭功能。在 JavaScript 部分的 signupClicked 函数下方添加以下代码:
function cancelButtonTapped() {
$('#user-info-popup').popup('hide')
}
保存文件并刷新浏览器,点击 “User Management” 链接,再点击 “Cancel” 按钮,对话框就会关闭。
接下来,为了实现认证功能,需要添加处理浏览器 Cookie 的函数。在 cancelButtonTapped 函数下方添加以下代码:
function setCookie(cookiename, cookievalue, hours) {
var date = new Date();
date.setTime(date.getTime() + Number(hours) * 3600 * 1000);
document.cookie = cookiename + "=" + cookievalue +
"; path=/;expires = " + date.toGMTString();
}
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
同时,更新 signupClicked 函数:
function signupClicked() {
$('#username-field').val(getCookie("username"))
$('#password-field').val(getCookie("password"))
$('#user-info-popup').popup('show')
}
这样,每次对话框弹出时,jQuery 会用最新存储的 Cookie 预填充字段。
以下是整个流程的 mermaid 流程图:
graph LR
A[打开项目并运行服务器] --> B[在浏览器打开指定页面]
B --> C[使用 Kitura OpenAPI UI 添加用户和条目]
C --> D[设置断点检查条目]
D --> E[编辑 home.stencil 文件添加元素]
E --> F[添加 JavaScript 代码关联操作]
F --> G[定义按钮点击函数]
G --> H[添加 Cookie 处理函数]
H --> I[更新 signupClicked 函数]
4. 实现注册和登录功能
在真正使用 JournalEntry API 之前,你需要编写注册和登录方法。
4.1 注册功能
在 JavaScript 代码底部添加以下函数:
function createUser() {
var userID = $('#username-field').val()
var password = $('#password-field').val()
var xhr = new XMLHttpRequest()
xhr.open("POST", "/user")
xhr.setRequestHeader("Content-Type", "application/json")
xhr.onreadystatechange = (() => {
if (xhr.readyState == XMLHttpRequest.DONE) {
$('#new-user-popup').popup('hide')
if (xhr.status == 201) {
var result =
confirm(`Created a new user: ${userID} - want to login?`)
if (result) {
login()
}
} else {
alert(`There was an error creating this user profile:
${xhr.statusText}`)
}
}
})
var body = JSON.stringify({"id": userID,
"password": password})
xhr.send(body)
}
这个函数通过 XMLHttpRequest 对象向服务器发送 POST 请求来创建新用户。当请求完成且状态码为 201 时,表示用户创建成功,会提示用户是否登录。
4.2 登录功能
在 createUser 函数下方添加以下代码:
function login() {
var userID = $('#username-field').val()
var password = $('#password-field').val()
var xhr = new XMLHttpRequest()
xhr.open("GET", "/entries")
xhr.setRequestHeader("Content-Type", "application/json")
xhr.setRequestHeader("Authorization", "Basic " +
btoa(userID + ":" + password))
xhr.onreadystatechange = (() => {
if (xhr.readyState == XMLHttpRequest.DONE) {
if (xhr.status == 200) {
// 1
setCookie("username", userID, 24)
setCookie("password", password, 24)
// 2
$('#user-info-popup').popup('hide')
// 3
alert(`Logged in as ${userID}`)
// 4
var loggedInUser = document.getElementById('logged-in')
loggedInUser.innerHTML = "Logged in as: " + userID
location.reload()
} else {
alert(`Login failed: ${xhr.statusText}`)
}
}
})
xhr.send()
}
这个函数通过 GET 请求检查用户凭证。若状态码为 200,表示登录成功,会将用户名和密码保存为 Cookie,隐藏用户管理弹出窗口,提示用户登录成功,并更新页面显示。
4.3 注销功能
在 login 函数下方添加以下代码:
function logout() {
if (confirm("Are you sure you want to log out?")) {
setCookie("username", "", 24)
setCookie("password", "", 24)
location.reload()
}
}
当用户确认注销时,会清除存储的 Cookie 并刷新页面。
5. 测试功能
保存文件并刷新网页,尝试使用新用户 “socrates” 和密码 “philosophy” 进行注册。注册成功后点击 “OK” 登录,你将看到已成功登录为 “Socrates”。刷新页面,你会发现仍然显示之前的日记条目,因为还未添加按用户过滤日记条目的逻辑。
以下是注册、登录和注销功能的操作步骤表格:
| 功能 | 操作步骤 |
| ---- | ---- |
| 注册 | 输入用户名和密码,点击 “Sign Up” 按钮,根据提示操作 |
| 登录 | 输入用户名和密码,点击 “Login” 按钮,若凭证正确则登录成功 |
| 注销 | 点击 “Logout” 按钮,确认后清除 Cookie 并刷新页面 |
整个功能实现的流程可以用以下 mermaid 流程图表示:
graph LR
A[输入注册信息] --> B[调用 createUser 函数]
B --> C{请求状态码是否为 201}
C -- 是 --> D[提示是否登录]
D -- 是 --> E[调用 login 函数]
C -- 否 --> F[提示创建用户错误]
E --> G{请求状态码是否为 200}
G -- 是 --> H[保存 Cookie,隐藏窗口,提示登录成功,更新页面]
G -- 否 --> I[提示登录失败]
J[点击 Logout 按钮] --> K[调用 logout 函数]
K --> L[清除 Cookie 并刷新页面]
通过以上步骤,你已经为 Web 客户端添加了认证、添加和删除功能,使其更加完善和实用。后续你可以进一步优化和拓展这些功能,如添加按用户过滤日记条目的逻辑等。
构建功能丰富的 Web 客户端:认证、添加与删除功能实现
6. 深入理解代码逻辑
为了更好地掌握已实现的功能,我们来深入分析一下代码逻辑。
6.1 XMLHttpRequest 的使用
在注册和登录功能中,都使用了 XMLHttpRequest 对象来与服务器进行通信。这个对象是浏览器提供的用于发送 HTTP 请求的工具,它的基本使用步骤如下:
1. 创建 XMLHttpRequest 对象: var xhr = new XMLHttpRequest()
2. 打开请求: xhr.open(method, url) ,其中 method 可以是 GET 、 POST 等, url 是请求的地址。
3. 设置请求头: xhr.setRequestHeader(header, value) ,例如设置请求的内容类型为 JSON。
4. 监听请求状态变化: xhr.onreadystatechange = callback ,在回调函数中处理请求结果。
5. 发送请求: xhr.send(data) ,如果是 POST 请求,需要将数据作为参数传递。
以下是一个简单的对比表格,展示注册和登录请求的不同:
| 请求类型 | 方法 | URL | 请求头 | 数据 |
| ---- | ---- | ---- | ---- | ---- |
| 注册 | POST | /user | Content-Type: application/json | {“id”: userID, “password”: password} |
| 登录 | GET | /entries | Content-Type: application/json
Authorization: Basic [base64(username:password)] | 无 |
6.2 Cookie 的管理
Cookie 用于在浏览器中存储用户的登录信息,方便后续的请求使用。 setCookie 和 getCookie 函数分别用于设置和获取 Cookie。
setCookie 函数的逻辑如下:
1. 创建一个 Date 对象,并设置过期时间。
2. 将 Cookie 名称、值和过期时间组合成一个字符串。
3. 将该字符串赋值给 document.cookie 。
getCookie 函数的逻辑如下:
1. 获取当前浏览器的所有 Cookie,并将其拼接成一个字符串。
2. 按名称分割字符串,找到对应的 Cookie 值。
3. 返回 Cookie 值。
7. 优化建议
虽然目前已经实现了基本的注册、登录和注销功能,但还有一些可以优化的地方。
7.1 错误处理
在实际应用中,应该对各种可能的错误情况进行更详细的处理。例如,当网络请求失败时,除了显示错误信息,还可以提供重试机制。可以在 xhr.onreadystatechange 回调函数中添加更多的错误处理逻辑,如下所示:
xhr.onreadystatechange = (() => {
if (xhr.readyState == XMLHttpRequest.DONE) {
if (xhr.status == 200) {
// 处理成功响应
} else if (xhr.status == 401) {
alert('Unauthorized: Invalid credentials');
} else if (xhr.status == 404) {
alert('Not Found: The requested resource does not exist');
} else {
alert(`An error occurred: ${xhr.statusText}`);
}
}
})
7.2 用户体验优化
- 可以添加加载动画,在发送请求时显示,让用户知道请求正在处理中。
- 对输入字段进行验证,例如检查用户名和密码是否为空,避免无效请求。
以下是一个简单的输入验证示例:
function createUser() {
var userID = $('#username-field').val();
var password = $('#password-field').val();
if (userID === '' || password === '') {
alert('Please enter a valid username and password');
return;
}
// 继续发送请求的代码
}
8. 总结
通过以上步骤,我们成功地为 Web 客户端添加了认证、注册、登录和注销功能。整个过程涉及到 HTML、JavaScript、jQuery 和 HTTP 请求等多个方面的知识。
以下是整个功能实现的关键步骤列表:
1. 完善 Web 布局,添加用户管理界面。
2. 让网页按钮生效,实现对话框的显示和关闭功能。
3. 管理 Cookie,存储用户登录信息。
4. 实现注册、登录和注销功能,与服务器进行通信。
5. 测试功能,确保各项操作正常。
未来,你可以进一步拓展这些功能,例如添加按用户过滤日记条目的逻辑,或者实现更复杂的用户权限管理。
整个功能实现的流程图如下:
graph LR
A[完善 Web 布局] --> B[按钮生效]
B --> C[管理 Cookie]
C --> D[实现注册、登录、注销功能]
D --> E[测试功能]
E --> F[拓展功能]
希望这篇文章能帮助你更好地理解和实现 Web 客户端的认证和用户管理功能。如果你有任何问题或建议,欢迎留言讨论。
超级会员免费看
1605

被折叠的 条评论
为什么被折叠?



