!1 merge wei into main

对之前页面的修复

Created-by: qingss0
Commit-by: qing
Merged-by: qingss0
Description: 引入validation.js,修改Content-Type
注册修复
dos2unix
修改后端登陆响应为json,修复登陆页面

See merge request: qingss0/micro_servers!1
This commit is contained in:
qingss0 committed 2026-07-21 22:31:56 +08:00
commit 5940759088
6 files changed
+276 -275

No files matched your search

+5 -1
View File
@@ -359,9 +359,13 @@ http::response<http::string_body> handleLogin(
std::string token = Base64::base64_encode(data); std::string token = Base64::base64_encode(data);
std::string sign = _PRIV.Sign(data); std::string sign = _PRIV.Sign(data);
json::value jv_rr = {
{"success", true},
{"data", json::object{{"token", token + "_" + sign}}} // 双大括号
};
res.set("Connection", "close"); res.set("Connection", "close");
res.result(http::status::ok); res.result(http::status::ok);
res.body() = token + "_" + sign; res.body() = json::serialize(jv_rr);
} }
catch (const HttpException& e) { catch (const HttpException& e) {
+111 -113
View File
@@ -1,40 +1,40 @@
const msgTip = document.getElementById('msgTip'); const msgTip = document.getElementById('msgTip');
const pwdTip = document.getElementById('pwdTip'); const pwdTip = document.getElementById('pwdTip');
const emlTip = document.getElementById('emlTip'); const emlTip = document.getElementById('emlTip');
const agreeTip = document.getElementById('agreeTip'); const agreeTip = document.getElementById('agreeTip');
const form = document.getElementById('form'); const form = document.getElementById('form');
const usernameInput = document.getElementById('loginUsername'); const usernameInput = document.getElementById('loginUsername');
const passwordInput = document.getElementById('loginPassword'); const passwordInput = document.getElementById('loginPassword');
const emailInput = document.getElementById('loginEmail'); const emailInput = document.getElementById('loginEmail');
const agreeBox = document.getElementById('agreeBox'); const agreeBox = document.getElementById('agreeBox');
const protocol = document.getElementById('agreement'); const protocol = document.getElementById('agreement');
const resetUser = document.getElementById('resetUser'); const resetUser = document.getElementById('resetUser');
const registerBtn = document.getElementById('registerBtn'); const registerBtn = document.getElementById('registerBtn');
const loginButton = document.getElementById('loginBtn'); const loginButton = document.getElementById('loginBtn');
resetUser.addEventListener('click', function() { resetUser.addEventListener('click', function() {
clearTipStyle(); clearTipStyle();
}); });
function clearTipStyle() { function clearTipStyle() {
msgTip.innerHTML = ''; msgTip.innerHTML = '';
pwdTip.innerHTML = ''; pwdTip.innerHTML = '';
agreeTip.innerHTML = ''; agreeTip.innerHTML = '';
emlTip.innerHTML = ''; emlTip.innerHTML = '';
msgTip.classList.remove('tip-red', 'tip-yellow', 'tip-green'); msgTip.classList.remove('tip-red', 'tip-yellow', 'tip-green');
pwdTip.classList.remove('tip-red', 'tip-yellow', 'tip-green'); pwdTip.classList.remove('tip-red', 'tip-yellow', 'tip-green');
agreeTip.classList.remove('tip-red', 'tip-yellow', 'tip-green'); agreeTip.classList.remove('tip-red', 'tip-yellow', 'tip-green');
emlTip.classList.remove('tip-red', 'tip-yellow', 'tip-green'); emlTip.classList.remove('tip-red', 'tip-yellow', 'tip-green');
protocol.classList.remove('tip-red'); protocol.classList.remove('tip-red');
protocol.classList.remove('tip-green'); protocol.classList.remove('tip-green');
} }
clearTipStyle(); clearTipStyle();
/** /**
* @returns {string|false} * @returns {string|false}
*/ */
function checkUsername() { function checkUsername() {
const result = FormValidators.username(usernameInput.value); const result = FormValidators.username(usernameInput.value);
msgTip.innerHTML = ''; msgTip.innerHTML = '';
@@ -42,11 +42,11 @@ function checkUsername() {
msgTip.textContent = result.message; msgTip.textContent = result.message;
msgTip.classList.add(result.className); msgTip.classList.add(result.className);
return result.valid ? result.value : false; return result.valid ? result.value : false;
} }
/** /**
* @returns {string|false} * @returns {string|false}
*/ */
function checkPwd() { function checkPwd() {
const result = FormValidators.password(passwordInput.value); const result = FormValidators.password(passwordInput.value);
pwdTip.innerHTML = ''; pwdTip.innerHTML = '';
@@ -54,11 +54,11 @@ function checkPwd() {
pwdTip.textContent = result.message; pwdTip.textContent = result.message;
pwdTip.classList.add(result.className); pwdTip.classList.add(result.className);
return result.valid ? result.value : false; return result.valid ? result.value : false;
} }
/** /**
* @returns {string|false} * @returns {string|false}
*/ */
function checkEml() { function checkEml() {
const result = FormValidators.email(emailInput.value); const result = FormValidators.email(emailInput.value);
emlTip.innerHTML = ''; emlTip.innerHTML = '';
@@ -66,71 +66,71 @@ function checkEml() {
emlTip.textContent = result.message; emlTip.textContent = result.message;
emlTip.classList.add(result.className); emlTip.classList.add(result.className);
return result.valid ? result.value : false; return result.valid ? result.value : false;
} }
/** /**
* @returns {boolean} * @returns {boolean}
*/ */
function checkAgree() { function checkAgree() {
agreeTip.innerHTML = ''; agreeTip.innerHTML = '';
agreeTip.classList.remove('tip-red'); agreeTip.classList.remove('tip-red');
protocol.classList.remove('tip-green', 'tip-red'); protocol.classList.remove('tip-green', 'tip-red');
if (!agreeBox.checked) { if (!agreeBox.checked) {
agreeTip.innerHTML = '请同意用户协议!'; agreeTip.innerHTML = '请同意用户协议!';
agreeTip.classList.add('tip-red'); agreeTip.classList.add('tip-red');
protocol.classList.add('tip-red'); protocol.classList.add('tip-red');
return false; return false;
} }
protocol.classList.add('tip-green'); protocol.classList.add('tip-green');
return true; return true;
} }
usernameInput.addEventListener('focus', checkUsername); usernameInput.addEventListener('focus', checkUsername);
passwordInput.addEventListener('focus', checkPwd); passwordInput.addEventListener('focus', checkPwd);
usernameInput.addEventListener('input', checkUsername); usernameInput.addEventListener('input', checkUsername);
passwordInput.addEventListener('input', checkPwd); passwordInput.addEventListener('input', checkPwd);
usernameInput.addEventListener('blur', checkUsername); usernameInput.addEventListener('blur', checkUsername);
passwordInput.addEventListener('blur', checkPwd); passwordInput.addEventListener('blur', checkPwd);
emailInput.addEventListener('focus', checkEml); emailInput.addEventListener('focus', checkEml);
emailInput.addEventListener('input', checkEml); emailInput.addEventListener('input', checkEml);
emailInput.addEventListener('blur', checkEml); emailInput.addEventListener('blur', checkEml);
agreeBox.addEventListener('change', checkAgree); agreeBox.addEventListener('change', checkAgree);
registerBtn.addEventListener('click', function() { registerBtn.addEventListener('click', function() {
location.href = 'register.html'; location.href = 'register.html';
}); });
form.addEventListener('submit', async function(e) { form.addEventListener('submit', async function(e) {
e.preventDefault(); e.preventDefault();
clearTipStyle(); clearTipStyle();
const userOk = checkUsername(); const userOk = checkUsername();
const pwdOk = checkPwd(); const pwdOk = checkPwd();
const emlOk = checkEml(); const emlOk = checkEml();
const agreeOk = checkAgree(); const agreeOk = checkAgree();
if (!(userOk && pwdOk && emlOk && agreeOk)) { if (!(userOk && pwdOk && emlOk && agreeOk)) {
return; return;
} }
const jsonBody = JSON.stringify({ const jsonBody = JSON.stringify({
username: userOk, username: userOk,
password: pwdOk password: pwdOk
}); });
try { try {
loginButton.disabled = true; loginButton.disabled = true;
const res = await fetch('/login', { const res = await fetch('/login', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/x-www-form-urlencoded' 'Content-Type': 'application/json' // 告诉服务器内容为json
}, },
body: jsonBody body: jsonBody
}); });
const responseText = await res.text(); const responseText = await res.text();
let result; let result;
@@ -146,19 +146,17 @@ form.addEventListener('submit', async function(e) {
throw new Error(result.message || `登录失败(HTTP ${res.status})`); throw new Error(result.message || `登录失败(HTTP ${res.status})`);
} }
if (result.code === 0) { if (result.success) {
if (!result.data || !result.data.token || !result.data.username) { alert(`登陆成功`);
throw new Error('登录成功,但服务器返回的数据不完整'); sessionStorage.setItem('token', result.data.token);
} location.href = 'main.html';
alert(`${result.message},账号:${result.data.username}`); } else {
sessionStorage.setItem('token', result.data.token);
location.href = 'main.html';
} else {
alert(result.message || '登录失败'); alert(result.message || '登录失败');
} }
} catch (err) {
} catch (err) {
alert(err.message || '接口请求失败,请检查后端服务是否启动'); alert(err.message || '接口请求失败,请检查后端服务是否启动');
console.error('登录请求异常:', err); console.error('登录请求异常:', err);
} finally { } finally {
loginButton.disabled = false; loginButton.disabled = false;
} }
+3 -5
View File
@@ -183,11 +183,8 @@ form.addEventListener('submit', async function (e) {
throw new Error(result.message || `注册失败(HTTP ${res.status})`); throw new Error(result.message || `注册失败(HTTP ${res.status})`);
} }
if (result.code === 0) { if (result.success) {
if (!result.data || !result.data.username) { alert('注册成功');
throw new Error('注册成功,但服务器返回的数据不完整');
}
alert(`${result.message},账号:${result.data.username}`);
form.reset(); form.reset();
sendCode = ''; sendCode = '';
codeTarget = ''; codeTarget = '';
@@ -196,6 +193,7 @@ form.addEventListener('submit', async function (e) {
} }
alert(result.message || '注册失败'); alert(result.message || '注册失败');
} catch (err) { } catch (err) {
console.error('注册请求异常:', err); console.error('注册请求异常:', err);
alert(err.message || '接口请求失败,请检查后端服务是否启动'); alert(err.message || '接口请求失败,请检查后端服务是否启动');
+40 -39
View File
@@ -1,47 +1,48 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<!-- 移动端适配核心标签 --> <!-- 移动端适配核心标签 -->
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<title>登录</title> <title>登录</title>
<style> <style>
.tip-red {color:red;} .tip-red {color:red;}
.tip-yellow {color: orange;} .tip-yellow {color: orange;}
.tip-green {color: greenyellow;} .tip-green {color: greenyellow;}
</style> </style>
</head> </head>
<body> <body>
<h2>用户登录</h2> <h2>用户登录</h2>
<form action="" id="form" method="post"> <form action="" id="form" method="post">
<div> <div>
<label>用户名/推荐邮箱:</label> <label>用户名/推荐邮箱:</label>
<input type="text" id="loginUsername" name="username" placeholder="请输入用户名"> <input type="text" id="loginUsername" name="username" placeholder="请输入用户名">
<span id="msgTip" ></span> <span id="msgTip" ></span>
<br> <br>
<label>密码:</label> <label>密码:</label>
<input type="password" id="loginPassword" name="password" placeholder="请输入密码"> <input type="password" id="loginPassword" name="password" placeholder="请输入密码">
<span id="pwdTip"></span> <span id="pwdTip"></span>
</div> </div>
<div> <div>
<label>验证邮箱:</label> <label>验证邮箱:</label>
<input type="email" id="loginEmail" name="email" placeholder="请输入验证邮箱"> <input type="email" id="loginEmail" name="email" placeholder="请输入验证邮箱">
<span id="emlSub"> <span id="emlSub">
<input type="submit" value="发送验证码"> <input type="submit" value="发送验证码">
</span> </span>
<span id="emlTip"></span> <span id="emlTip"></span>
</div> </div>
<div> <div>
<button type="button" id="registerBtn">注册</button> <button type="button" id="registerBtn">注册</button>
<input type="submit" id="loginBtn" value="登录"> <input type="submit" id="loginBtn" value="登录">
<input type="reset" id="resetUser" value="重置"> <input type="reset" id="resetUser" value="重置">
</div> </div>
<div> <div>
<input type="checkbox" id="agreeBox" name="agree" value="access"> <input type="checkbox" id="agreeBox" name="agree" value="access">
<label id="agreement">同意该系统相关用户使用条例</label> <label id="agreement">同意该系统相关用户使用条例</label>
<span id="agreeTip"></span> <span id="agreeTip"></span>
</div> </div>
</form> </form>
<script src="js/validation.js"></script>
<script src="js/login.js"></script> <script src="js/login.js"></script>
</body> </body>
</html> </html>
+101 -101
View File
@@ -1,102 +1,102 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<!-- 移动端适配核心标签 --> <!-- 移动端适配核心标签 -->
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<title>DNFS · 树状笔记</title> <title>DNFS · 树状笔记</title>
<style></style> <style></style>
</head> </head>
<body> <body>
<!-- 文章主标题 --> <!-- 文章主标题 -->
<div id="article-title"> <div id="article-title">
<h1> <h1>
<p>Python</p> <p>Python</p>
</h1> </h1>
</div> </div>
<!-- 文章详情 --> <!-- 文章详情 -->
<div id="publish-time"> <div id="publish-time">
<p>发布时间:2026-07-11</p> <p>发布时间:2026-07-11</p>
</div> </div>
<div> <div>
<span id="visit-count">浏览:126</span> <span id="visit-count">浏览:126</span>
<span id="like-count">点赞:28</span> <span id="like-count">点赞:28</span>
<span id="share-count">分享:7</span> <span id="share-count">分享:7</span>
</div> </div>
<!-- 文章正文--> <!-- 文章正文-->
<div id="article-content"> <div id="article-content">
<p> <p>
Python 的 <code>socket</code> Python 的 <code>socket</code>
模块是网络编程的核心,其函数可分为<strong>核心套接字操作</strong>、<strong>套接字选项设置</strong>、<strong>辅助工具函数</strong>三大类。本文将逐一拆解所有函数的语法、参数、用法和实战示例,覆盖从基础到高级的所有场景。 模块是网络编程的核心,其函数可分为<strong>核心套接字操作</strong>、<strong>套接字选项设置</strong>、<strong>辅助工具函数</strong>三大类。本文将逐一拆解所有函数的语法、参数、用法和实战示例,覆盖从基础到高级的所有场景。
</p> </p>
<h2>一、模块初始化与核心对象</h2> <h2>一、模块初始化与核心对象</h2>
<h3>1. socket.socket():创建套接字对象</h3> <h3>1. socket.socket():创建套接字对象</h3>
<p><strong>语法</strong>:</p> <p><strong>语法</strong>:</p>
<pre><code>socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)</code></pre> <pre><code>socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)</code></pre>
<p><strong>作用</strong>:创建一个套接字对象,是所有网络操作的基础。</p> <p><strong>作用</strong>:创建一个套接字对象,是所有网络操作的基础。</p>
<p><strong>参数说明</strong>:</p> <p><strong>参数说明</strong>:</p>
<table> <table>
<tr> <tr>
<th>参数</th> <th>参数</th>
<th>取值</th> <th>取值</th>
<th>说明</th> <th>说明</th>
</tr> </tr>
<tr> <tr>
<td><code>family</code></td> <td><code>family</code></td>
<td><code>AF_INET</code>(默认)</td> <td><code>AF_INET</code>(默认)</td>
<td>IPv4 协议族(最常用)</td> <td>IPv4 协议族(最常用)</td>
</tr> </tr>
<tr> <tr>
<td></td> <td></td>
<td><code>AF_INET6</code></td> <td><code>AF_INET6</code></td>
<td>IPv6 协议族</td> <td>IPv6 协议族</td>
</tr> </tr>
<tr> <tr>
<td></td> <td></td>
<td><code>AF_UNIX</code></td> <td><code>AF_UNIX</code></td>
<td>Unix 域套接字(本地进程通信)</td> <td>Unix 域套接字(本地进程通信)</td>
</tr> </tr>
<tr> <tr>
<td><code>type</code></td> <td><code>type</code></td>
<td><code>SOCK_STREAM</code>(默认)</td> <td><code>SOCK_STREAM</code>(默认)</td>
<td>TCP 套接字(面向连接、可靠)</td> <td>TCP 套接字(面向连接、可靠)</td>
</tr> </tr>
<tr> <tr>
<td></td> <td></td>
<td><code>SOCK_DGRAM</code></td> <td><code>SOCK_DGRAM</code></td>
<td>UDP 套接字(无连接、数据报)</td> <td>UDP 套接字(无连接、数据报)</td>
</tr> </tr>
<tr> <tr>
<td></td> <td></td>
<td><code>SOCK_RAW</code></td> <td><code>SOCK_RAW</code></td>
<td>原始套接字(可操作 IP 层,用于抓包)</td> <td>原始套接字(可操作 IP 层,用于抓包)</td>
</tr> </tr>
<tr> <tr>
<td><code>proto</code></td> <td><code>proto</code></td>
<td>0(默认)</td> <td>0(默认)</td>
<td>协议编号,默认自动匹配 type(TCP=6,UDP=17)</td> <td>协议编号,默认自动匹配 type(TCP=6,UDP=17)</td>
</tr> </tr>
<tr> <tr>
<td><code>fileno</code></td> <td><code>fileno</code></td>
<td>None(默认)</td> <td>None(默认)</td>
<td>复用已有文件描述符,无需手动指定</td> <td>复用已有文件描述符,无需手动指定</td>
</tr> </tr>
</table> </table>
</div> </div>
<div class="other-recommend"> <div class="other-recommend">
<h3>其他推荐</h3> <h3>其他推荐</h3>
</div> </div>
<div class="recommend-list" id="recommend-list"> <div class="recommend-list" id="recommend-list">
<ul> <ul>
<li><a href="https://www.baidu.com">百度推荐</a></li> <li><a href="https://www.baidu.com">百度推荐</a></li>
<li><a href="https://www.baidu.com">百度推荐</a></li> <li><a href="https://www.baidu.com">百度推荐</a></li>
<li><a href="https://www.baidu.com">百度推荐</a></li> <li><a href="https://www.baidu.com">百度推荐</a></li>
<li><a href="https://www.baidu.com">百度推荐</a></li> <li><a href="https://www.baidu.com">百度推荐</a></li>
<li><a href="https://www.baidu.com">百度推荐</a></li> <li><a href="https://www.baidu.com">百度推荐</a></li>
</ul> </ul>
</div> </div>
</body> </body>
</html> </html>
+16 -16
View File
@@ -1,32 +1,32 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<title>注册页面</title> <title>注册页面</title>
<style> <style>
.tip-red {color:red;} .tip-red {color:red;}
.tip-yellow {color: orange;} .tip-yellow {color: orange;}
.tip-green {color: greenyellow;} .tip-green {color: greenyellow;}
</style> </style>
</head> </head>
<body> <body>
<h2>注册页面</h2> <h2>注册页面</h2>
<form id="form"> <form id="form">
<div> <div>
<label>用户名/推荐邮箱:</label> <label>用户名/推荐邮箱:</label>
<input type="text" id="regusername" placeholder="请输入用户名"> <input type="text" id="regusername" placeholder="请输入用户名">
<span id="msgTip" ></span> <span id="msgTip" ></span>
<br> <br>
<label>邮箱号:</label> <label>邮箱号:</label>
<input type="email" id="regemail" placeholder="请输入邮箱号"> <input type="email" id="regemail" placeholder="请输入邮箱号">
<div class="code-box">验证码: <div class="code-box">验证码:
<input type="text" id="code" placeholder="请输入6位验证码" inputmode="numeric" maxlength="6"> <input type="text" id="code" placeholder="请输入6位验证码" inputmode="numeric" maxlength="6">
<input type="button" id="getCode" value="获取验证码"> <input type="button" id="getCode" value="获取验证码">
<span id="codeTip"></span> <span id="codeTip"></span>
</div> </div>
<span id="emlTip"></span> <span id="emlTip"></span>
<br> <br>
<label>密码:</label> <label>密码:</label>
<input type="password" id="regpsw" placeholder="密码至少6位"> <input type="password" id="regpsw" placeholder="密码至少6位">
<label>验证密码:</label> <label>验证密码:</label>