![图片[1]-给Chevereto游客用户上传文件增加一个弹窗提示-鼎点&Blog](https://wp-blog.obs.cn-east-3.myhuaweicloud.com/wp-content/uploads/2026/10/image-74-1024x514.png)
上图的效果:用户未登录状态时上传文件会提示,登录状态下不提示
这样的效果该怎么实现呢,接下来先讲讲原理,大家可以跟着操作一起整起来!
Chevereto 游客上传提示弹窗完整实现教程:
一、前言
在使用 Chevereto 搭建图片、视频托管站时,如果允许游客直接上传文件,通常需要向游客明确说明:
- 当前正在以游客身份上传;
- 游客上传的文件只保留一定时间;
- 文件到期后会自动清理;
- 注册账号后可以更加方便地管理自己的文件。
本文介绍一种无需修改 Chevereto 核心程序文件的实现方式,通过后台自定义 JavaScript 动态创建提示弹窗。
最终实现的效果是:
只有游客访问 /upload 上传页面时才显示提示。
同时不会影响正常上传,也不会干扰登录、注册和账户相关页面。
二、最终实现效果
游客访问:
游客访问:
https://你的域名/upload
会显示一个提示弹窗:
┌──────────────────────────────┐
│ │
│ ☁ │
│ │
│ 游客上传提示 │
│ │
│ 您当前正在以游客身份上传文件。 │
│ 游客上传的图片、视频等文件 │
│ 仅保留 7 天,到期后将自动清理。 │
│ │
│ 注册账号后可以更加方便地管理文件。│
│ │
│ 登录 注册 知道了 │
│ │
└──────────────────────────────┘
其中:
- 登录:进入登录页面;
- 注册:进入注册页面;
- 知道了:关闭提示,不进行任何跳转;
- 右上角
×:关闭提示; - 点击弹窗外部遮罩:关闭提示;
- 按键盘
Esc:关闭提示。
三、功能规则
本方案的判断规则如下。
| 场景 | 是否显示 |
|---|---|
游客访问 /upload | ✅ 显示 |
已登录用户访问 /upload | ❌ 不显示 |
游客访问首页 / | ❌ 不显示 |
游客访问 /login | ❌ 不显示 |
游客访问 /signup | ❌ 不显示 |
游客访问 /register | ❌ 不显示 |
游客访问 /account | ❌ 不显示 |
游客访问 /account/* | ❌ 不显示 |
| 游客访问找回密码页面 | ❌ 不显示 |
| 点击“知道了” | ❌ 当前页面不再重复显示 |
| 刷新页面 | ✅ 重新显示 |
| 离开上传页面后再次进入 | ✅ 重新显示 |
这里特别需要说明:
“知道了”不会永久记住用户。
本方案不使用:
- Cookie
- localStorage
- sessionStorage
而是使用一个 JavaScript 内存变量记录当前页面是否关闭过弹窗。
因此刷新页面后,状态会自动恢复。
四、核心判断逻辑
整个功能实际上可以归纳为一个非常简单的判断公式:
显示弹窗
=
当前页面是 /upload
AND
当前页面不是排除页面
AND
用户没有登录
AND
当前页面没有关闭过弹窗
也就是:
if (
是上传页面 &&
不是排除页面 &&
没有登录 &&
没有点击过“知道了”
) {
显示弹窗;
}
整个程序按照这个顺序进行判断。
五、判断流程
完整流程如下:
页面加载
│
▼
获取当前 URL 路径
│
▼
是否为 /upload?
│
├── 否 → 结束
│
▼
是否属于排除页面?
│
├── 是 → 结束
│
▼
是否已经登录?
│
├── 是 → 结束
│
▼
当前页面是否已经点击“知道了”?
│
├── 是 → 结束
│
▼
显示游客提示弹窗
这种设计的好处是:
先过滤页面,再判断身份,最后判断弹窗状态。
避免不必要地创建弹窗。
六、获取当前页面路径
使用:
window.location.pathname
获取当前 URL 的路径。
例如:
https://img.example.com/upload
得到:
/upload
代码:
function getCurrentPath() {
var path = window.location.pathname || '/';
path = path.replace(/\/+$/, '');
if (path === '') {
path = '/';
}
return path;
}
同时处理了:
/upload
/upload/
两种情况。
最终都会统一为:
/upload
七、判断是否为上传页面
定义:
var NOTICE_PAGE = '/upload';
然后通过:
function isNoticePage(path) {
return path === NOTICE_PAGE;
}
进行判断。
只有:
/upload
才允许继续执行。
例如:
/
不会显示。
/login
不会显示。
/account
不会显示。
八、排除页面机制
虽然目前弹窗只针对 /upload,但代码仍然保留了一套排除页面机制。
var EXCLUDED_PATHS = [
'/login',
'/signup',
'/register',
'/account',
'/account/password-forgot',
'/account/password-reset'
];
这样以后如果修改功能,例如需要让弹窗同时出现在首页,只需要调整:
NOTICE_PAGE
即可,而不需要重新设计整套判断逻辑。
/account/* 的特殊处理
账户页面可能存在:
/account
/account/profile
/account/settings
/account/password
所以不能只判断:
path === '/account'
程序还会判断:
path.indexOf('/account/') === 0
因此:
/account
/account/xxx
/account/xxx/xxx
都会被认为是账户页面。
九、登录状态判断
本方案没有通过 URL 中是否存在 /login 来判断用户身份。
也没有通过:
a[href="/login"]
或者其他容易受到页面结构变化影响的元素判断。
而是使用 Chevereto 页面中登录用户存在的退出登录表单:
#form-logout
判断代码:
function isLoggedIn() {
return document.querySelector('#form-logout') !== null;
}
逻辑非常简单:
存在 #form-logout
↓
已登录
如果不存在:
不存在 #form-logout
↓
游客
因此登录用户进入:
/upload
时,程序会直接停止,不会显示游客提示。
十、当前页面临时关闭机制
这是本方案比较重要的一点。
定义:
var noticeDismissed = false;
初始状态:
false
表示:
当前页面还没有关闭过弹窗。
用户点击:
知道了
之后:
noticeDismissed = true;
同时删除弹窗。
以后程序再次执行初始化时:
if (noticeDismissed) {
return;
}
因此当前页面不会再次显示。
为什么刷新后又会显示?
因为这个变量只存在于当前页面的 JavaScript 内存中。
刷新浏览器后:
网页重新加载
↓
JavaScript重新执行
↓
noticeDismissed重新初始化
↓
false
↓
允许重新显示弹窗
因此:
进入 /upload
↓
弹窗
↓
点击“知道了”
↓
当前页面不再弹
↓
刷新页面
↓
重新弹
这种方式特别适合“本次访问期间不要重复打扰用户,但下次访问仍然提醒”的场景。
十一、完整 JavaScript 代码
下面是最终完整代码。
注意:
这是纯 JavaScript。
如果 Chevereto 后台的自定义 JS 输入框要求填写 JavaScript,直接粘贴下面代码即可。
不要额外添加 <script> 和 </script> 标签。
(function () {
'use strict';
/* =========================================================
* 浮光游客上传提示
* ========================================================= */
var NOTICE_PAGE = '/upload';
var EXCLUDED_PATHS = [
'/login',
'/signup',
'/register',
'/account',
'/account/password-forgot',
'/account/password-reset'
];
/*
* 当前页面生命周期内的关闭状态
*
* 不使用 Cookie
* 不使用 localStorage
* 不使用 sessionStorage
*
* 刷新页面后重新显示。
*/
var noticeDismissed = false;
/* =========================================================
* 获取当前路径
* ========================================================= */
function getCurrentPath() {
var path = window.location.pathname || '/';
path = path.replace(/\/+$/, '');
if (path === '') {
path = '/';
}
return path;
}
/* =========================================================
* 判断是否为排除页面
* ========================================================= */
function isExcludedPage(path) {
var i;
for (i = 0; i < EXCLUDED_PATHS.length; i++) {
if (path === EXCLUDED_PATHS[i]) {
return true;
}
if (
EXCLUDED_PATHS[i] === '/account' &&
path.indexOf('/account/') === 0
) {
return true;
}
}
return false;
}
/* =========================================================
* 判断当前是否为上传页面
* ========================================================= */
function isNoticePage(path) {
return path === NOTICE_PAGE;
}
/* =========================================================
* 判断登录状态
* ========================================================= */
function isLoggedIn() {
return document.querySelector(
'#form-logout'
) !== null;
}
/* =========================================================
* 判断弹窗是否已经存在
* ========================================================= */
function popupExists() {
return document.getElementById(
'fg-notice-mask'
) !== null;
}
/* =========================================================
* 创建元素
* ========================================================= */
function createElement(tag, css) {
var element =
document.createElement(tag);
if (css) {
element.style.cssText = css;
}
return element;
}
/* =========================================================
* 创建弹窗
* ========================================================= */
function createPopup() {
if (!document.body) {
return;
}
if (popupExists()) {
return;
}
if (noticeDismissed) {
return;
}
/* =====================================================
* 毛玻璃遮罩
* ===================================================== */
var mask = createElement(
'div',
'position:fixed;' +
'left:0;' +
'top:0;' +
'right:0;' +
'bottom:0;' +
'width:100vw;' +
'height:100vh;' +
'box-sizing:border-box;' +
'display:flex;' +
'align-items:center;' +
'justify-content:center;' +
'padding:20px;' +
/*
* 毛玻璃
*/
'background:rgba(15,23,42,0.35);' +
'backdrop-filter:blur(10px);' +
'-webkit-backdrop-filter:blur(10px);' +
'z-index:2147483647;' +
'font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",' +
'"Microsoft YaHei",Arial,sans-serif;'
);
mask.id = 'fg-notice-mask';
/* =====================================================
* 弹窗卡片
* ===================================================== */
var box = createElement(
'div',
'position:relative;' +
'display:block;' +
'width:calc(100% - 40px);' +
'max-width:430px;' +
'min-height:200px;' +
'padding:30px;' +
'box-sizing:border-box;' +
'background:#ffffff;' +
'color:#1e293b;' +
'border-radius:22px;' +
/*
* 柔和阴影
*/
'box-shadow:' +
'0 25px 70px rgba(0,0,0,0.25),' +
'0 0 50px rgba(99,102,241,0.18);' +
'text-align:center;' +
'opacity:1;' +
'visibility:visible;' +
'transform:none;' +
'overflow:hidden;'
);
box.id = 'fg-notice-box';
/* =====================================================
* 右上角关闭
* ===================================================== */
var closeButton = createElement(
'button',
'position:absolute;' +
'top:12px;' +
'right:14px;' +
'width:32px;' +
'height:32px;' +
'padding:0;' +
'margin:0;' +
'border:0;' +
'background:transparent;' +
'color:#94a3b8;' +
'font-size:24px;' +
'font-weight:400;' +
'line-height:32px;' +
'cursor:pointer;' +
'text-align:center;'
);
closeButton.id = 'fg-notice-x';
closeButton.type = 'button';
closeButton.innerHTML = '×';
/* =====================================================
* 蓝色云朵图标
* ===================================================== */
var icon = createElement(
'div',
'width:64px;' +
'height:64px;' +
'margin:0 auto 18px;' +
'border-radius:50%;' +
/*
* 蓝色渐变
*/
'background:linear-gradient(135deg,#4facfe,#1677ff);' +
'display:flex;' +
'align-items:center;' +
'justify-content:center;' +
'color:#ffffff;' +
'font-size:30px;' +
'line-height:64px;' +
/*
* 蓝色光晕
*/
'box-shadow:0 10px 25px rgba(22,119,255,0.25);'
);
icon.textContent = '☁';
/* =====================================================
* 标题
* ===================================================== */
var title = createElement(
'div',
'display:block;' +
'margin:0 0 18px 0;' +
'color:#111827;' +
'font-size:24px;' +
'font-weight:700;' +
'line-height:1.4;'
);
title.id = 'fg-notice-title';
title.textContent = '游客上传提示';
/* =====================================================
* 正文
* ===================================================== */
var text = createElement(
'div',
'display:block;' +
'margin:0;' +
'color:#475569;' +
'font-size:15px;' +
'line-height:1.8;'
);
text.id = 'fg-notice-text';
text.appendChild(
document.createTextNode(
'您当前正在以游客身份上传文件。'
)
);
text.appendChild(
document.createElement('br')
);
text.appendChild(
document.createTextNode(
'游客上传的图片、视频等文件'
)
);
text.appendChild(
document.createElement('br')
);
/* =====================================================
* 蓝色高亮标签
* ===================================================== */
var days = createElement(
'span',
'display:inline-block;' +
'margin:15px 0;' +
'padding:8px 16px;' +
'border-radius:999px;' +
/*
* 浅蓝背景
*/
'background:#eef6ff;' +
/*
* 蓝色文字
*/
'color:#1677ff;' +
'font-size:15px;' +
'font-weight:700;' +
'line-height:1.4;' +
'border:1px solid rgba(22,119,255,0.08);'
);
days.id = 'fg-notice-days';
days.textContent = '仅保留 7 天';
text.appendChild(days);
text.appendChild(
document.createTextNode(
',到期后将自动清理。'
)
);
/* =====================================================
* 提示
* ===================================================== */
var tip = createElement(
'div',
'display:block;' +
'margin:10px 0 24px 0;' +
'padding:10px 14px;' +
'box-sizing:border-box;' +
'background:#f5f9ff;' +
'border-radius:12px;' +
'color:#64748b;' +
'font-size:13px;' +
'line-height:1.7;'
);
tip.id = 'fg-notice-tip';
tip.textContent =
'注册账号后可以更加方便地管理您的文件。';
/* =====================================================
* 按钮容器
* ===================================================== */
var buttons = createElement(
'div',
'display:flex;' +
'gap:10px;' +
'justify-content:center;' +
'align-items:center;' +
'width:100%;' +
'box-sizing:border-box;'
);
buttons.id = 'fg-notice-buttons';
/* =====================================================
* 登录按钮
* 蓝色
* ===================================================== */
var login = createElement(
'a',
'display:inline-flex;' +
'align-items:center;' +
'justify-content:center;' +
'min-width:100px;' +
'height:44px;' +
'padding:0 20px;' +
'box-sizing:border-box;' +
'border:0;' +
'border-radius:12px;' +
/*
* 蓝色渐变
*/
'background:linear-gradient(135deg,#4facfe,#1677ff);' +
'color:#ffffff;' +
'font-size:14px;' +
'font-weight:600;' +
'cursor:pointer;' +
'text-decoration:none;' +
/*
* 蓝色阴影
*/
'box-shadow:0 8px 20px rgba(22,119,255,0.22);' +
'transition:all .2s ease;'
);
login.id = 'fg-notice-login';
login.href = '/login';
login.textContent = '登录';
/* =====================================================
* 注册按钮
* 绿色
* ===================================================== */
var register = createElement(
'a',
'display:inline-flex;' +
'align-items:center;' +
'justify-content:center;' +
'min-width:100px;' +
'height:44px;' +
'padding:0 20px;' +
'box-sizing:border-box;' +
'border:0;' +
'border-radius:12px;' +
/*
* 绿色渐变
*/
'background:linear-gradient(135deg,#34d399,#10b981);' +
'color:#ffffff;' +
'font-size:14px;' +
'font-weight:600;' +
'cursor:pointer;' +
'text-decoration:none;' +
/*
* 绿色阴影
*/
'box-shadow:0 8px 20px rgba(16,185,129,0.20);' +
'transition:all .2s ease;'
);
register.id = 'fg-notice-register';
register.href = '/signup';
register.textContent = '注册';
/* =====================================================
* 知道了按钮
* 灰色
* ===================================================== */
var knowButton = createElement(
'button',
'display:inline-flex;' +
'align-items:center;' +
'justify-content:center;' +
'min-width:100px;' +
'height:44px;' +
'padding:0 20px;' +
'box-sizing:border-box;' +
'border:1px solid #e2e8f0;' +
'border-radius:12px;' +
'background:#f1f5f9;' +
'color:#475569;' +
'font-size:14px;' +
'font-weight:600;' +
'cursor:pointer;' +
'transition:all .2s ease;'
);
knowButton.id = 'fg-notice-close';
knowButton.type = 'button';
knowButton.textContent = '知道了';
/* =====================================================
* 加入按钮
* ===================================================== */
buttons.appendChild(login);
buttons.appendChild(register);
buttons.appendChild(knowButton);
/* =====================================================
* 组装弹窗
* ===================================================== */
box.appendChild(closeButton);
box.appendChild(icon);
box.appendChild(title);
box.appendChild(text);
box.appendChild(tip);
box.appendChild(buttons);
mask.appendChild(box);
document.body.appendChild(mask);
/* =====================================================
* 手机端布局
* ===================================================== */
function applyResponsiveLayout() {
var isMobile =
window.matchMedia &&
window.matchMedia(
'(max-width: 480px)'
).matches;
if (isMobile) {
box.style.padding =
'26px 20px';
buttons.style.flexDirection =
'column';
login.style.width =
'100%';
register.style.width =
'100%';
knowButton.style.width =
'100%';
} else {
box.style.padding =
'30px';
buttons.style.flexDirection =
'row';
login.style.width =
'';
register.style.width =
'';
knowButton.style.width =
'';
}
}
applyResponsiveLayout();
window.addEventListener(
'resize',
applyResponsiveLayout
);
/* =====================================================
* 关闭弹窗
* ===================================================== */
function closePopup() {
noticeDismissed = true;
if (
mask &&
mask.parentNode
) {
mask.parentNode.removeChild(mask);
}
window.removeEventListener(
'resize',
applyResponsiveLayout
);
document.removeEventListener(
'keydown',
keyHandler
);
}
/* =====================================================
* ×
* ===================================================== */
closeButton.addEventListener(
'click',
closePopup
);
/* =====================================================
* 知道了
* ===================================================== */
knowButton.addEventListener(
'click',
closePopup
);
/* =====================================================
* 点击遮罩
* ===================================================== */
mask.addEventListener(
'click',
function (event) {
if (
event.target === mask
) {
closePopup();
}
}
);
/* =====================================================
* 阻止卡片内部点击冒泡
* ===================================================== */
box.addEventListener(
'click',
function (event) {
event.stopPropagation();
}
);
/* =====================================================
* ESC
* ===================================================== */
function keyHandler(event) {
if (
event.key === 'Escape'
) {
closePopup();
}
}
document.addEventListener(
'keydown',
keyHandler
);
/* =====================================================
* 控制台
* ===================================================== */
console.log(
'[浮光游客提示] 游客上传提示已显示'
);
}
/* =========================================================
* 初始化
* ========================================================= */
function init() {
var path =
getCurrentPath();
var noticePage =
isNoticePage(path);
var excluded =
isExcludedPage(path);
var loggedIn =
isLoggedIn();
console.log(
'[浮光游客提示]',
'path:',
path,
'noticePage:',
noticePage,
'excluded:',
excluded,
'loggedIn:',
loggedIn,
'dismissed:',
noticeDismissed
);
if (!noticePage) {
return;
}
if (excluded) {
return;
}
if (loggedIn) {
return;
}
if (noticeDismissed) {
return;
}
createPopup();
}
/* =========================================================
* 启动
* ========================================================= */
function start() {
if (!document.body) {
setTimeout(
start,
100
);
return;
}
setTimeout(
init,
500
);
}
/* =========================================================
* DOM Ready
* ========================================================= */
if (
document.readyState === 'loading'
) {
document.addEventListener(
'DOMContentLoaded',
start
);
} else {
start();
}
})();
十二、部署步骤
第一步:进入 Chevereto 后台
进入你的 Chevereto 管理后台。
找到网站的:
自定义 JavaScript / Custom JS
![图片[2]-给Chevereto游客用户上传文件增加一个弹窗提示-鼎点&Blog](https://wp-blog.obs.cn-east-3.myhuaweicloud.com/wp-content/uploads/2026/10/image-75-1024x514.png)
第二步:删除旧代码
如果之前已经添加过游客提示代码:
先把旧代码全部删除。
不要将新代码追加到旧代码后面。
否则可能出现:
- 弹窗出现两次;
- 两套关闭事件同时执行;
- CSS 样式冲突;
- 控制台出现重复日志。
第三步:粘贴完整代码
将本文“完整 JavaScript 代码”中的内容全部复制。
直接粘贴到 Chevereto 的自定义 JS 输入框。
特别注意
不要添加:
<script>
也不要添加:
</script>
因为后台的自定义 JS 输入框本身就是 JavaScript 执行环境。
正确:
(function () {
...
})();
错误:
<script>
(function () {
...
})();
</script>
十三、保存后测试
建议按照下面的顺序进行测试。
测试 1:游客访问上传页面
使用浏览器隐身窗口,或者退出当前账号。
打开:
https://你的域名/upload
应该显示:
游客上传提示
测试 2:点击“知道了”
点击:
知道了
应该立即关闭弹窗。
然后正常使用上传功能。
不会跳转登录,也不会跳转注册。
测试 3:刷新页面
在 /upload 页面按:
Ctrl + R
或者:
F5
刷新。
弹窗应该重新出现。
这是因为:
noticeDismissed
只存在于当前页面的 JavaScript 内存中。
测试 4:登录后访问上传页面
登录账号。
然后进入:
/upload
应该:
不显示弹窗。
因为登录用户页面存在:
#form-logout
程序检测到已经登录后直接结束。
测试 5:首页
访问:
/
应该:
不显示弹窗。
测试 6:登录页面
访问:
/login
应该:
不显示弹窗。
测试 7:注册页面
访问:
/signup
应该:
不显示弹窗。
十四、如何使用浏览器控制台排查
如果出现问题,可以按:
F12
打开浏览器开发者工具。
然后进入:
Console / 控制台
正常情况下,可以看到类似:
[浮光游客提示]
path: /upload
noticePage: true
excluded: false
loggedIn: false
dismissed: false
然后:
[浮光游客提示] 游客上传提示已显示
这说明:
当前页面:/upload
页面符合要求:true
没有被排除:false
当前没有登录:false
当前还没有关闭弹窗:false
因此最终显示弹窗。
十五、不同情况下控制台结果
游客 /upload
path: /upload
noticePage: true
excluded: false
loggedIn: false
dismissed: false
结果:
显示弹窗
登录用户 /upload
path: /upload
noticePage: true
excluded: false
loggedIn: true
dismissed: false
结果:
不显示
因为:
if (loggedIn) {
return;
}
游客首页
path: /
noticePage: false
结果:
不显示
游客点击“知道了”后
状态变成:
dismissed: true
结果:
不再创建弹窗
刷新页面后
重新初始化:
dismissed: false
结果:
再次显示弹窗
十六、常见问题
1. 为什么保存代码后没有效果?
首先确认:
不要添加 <script> 标签。
后台自定义 JS 中应该直接填写:
(function () {
...
})();
而不是:
<script>
...
</script>
然后清除浏览器缓存,再重新打开 /upload。
2. 为什么登录用户也出现弹窗?
打开 F12 → Console。
查看:
loggedIn
正常登录用户应该是:
loggedIn: true
如果仍然是:
loggedIn: false
说明当前 Chevereto 版本的登录状态页面结构可能发生了变化,需要重新确认登录用户页面中的退出登录元素。
3. 为什么首页也出现弹窗?
检查:
path
首页应该显示:
path: /
同时:
noticePage: false
如果首页仍然弹窗,通常说明页面中存在旧版游客提示代码。
建议:
- 删除所有旧代码;
- 只保留本文这一份代码;
- 清除浏览器缓存;
- 重新测试。
4. 为什么点击“知道了”之后刷新还不弹?
本文代码本身不会持久化关闭状态。
它没有使用:
Cookie
localStorage
sessionStorage
所以刷新以后:
noticeDismissed
一定会重新初始化为:
false
如果刷新后没有弹,应该重点检查:
loggedIn
noticePage
excluded
这三个判断条件。
5. 为什么点击“知道了”以后又马上出现?
如果出现这种情况,通常意味着页面存在其他 JavaScript 再次调用弹窗初始化,或者同时存在旧版本代码。
可以检查:
[浮光游客提示]
是否在控制台出现多次。
如果出现多个版本的初始化日志,建议删除旧代码,只保留当前版本。
6. 点击弹窗外部为什么也可以关闭?
这是代码主动设计的功能。
实现:
mask.addEventListener(
'click',
function (event) {
if (event.target === mask) {
closePopup();
}
}
);
只有点击黑色遮罩本身才会关闭。
点击弹窗内容不会触发关闭。
7. 为什么点击 ESC 也能关闭?
代码监听了:
event.key === 'Escape'
因此用户按键盘:
Esc
也可以关闭弹窗。
关闭后同样会设置:
noticeDismissed = true;
因此当前页面不会再次弹出。
十七、如何修改提示内容?
如果以后需要修改提示文字,只需要修改:
text.appendChild(
document.createTextNode('您当前正在以游客身份上传文件。')
);
例如改成:
text.appendChild(
document.createTextNode('游客上传的文件仅保留 7 天。')
);
“注册后”的提示则修改:
tip.textContent =
'注册账号后可以更加方便地管理您的文件。';
十八、如何修改保留时间?
目前显示:
仅保留 7 天
对应:
days.textContent = '仅保留 7 天';
例如实际策略变成 30 天,只需要修改:
days.textContent = '仅保留 30 天';
需要注意:
JavaScript 这里只负责显示提示文字,并不会改变 Chevereto 实际文件的保存周期。
如果服务器实际设置的是 7 天,而这里只写 30 天,那么只是显示内容与实际策略不一致。
因此提示文字应该和网站实际的游客文件清理策略保持一致。
十九、如何修改弹窗按钮?
目前三个按钮:
登录
注册
知道了
登录地址:
login.href = '/login';
注册地址:
register.href = '/signup';
如果你的站点注册地址不同,可以直接修改。
例如:
register.href = '/register';
二十、为什么推荐动态创建弹窗?
这种方案最大的优点是:
不修改 Chevereto 核心文件
不会直接修改:
PHP
模板文件
核心 JS
核心 CSS
因此 Chevereto 后续升级时,理论上不会因为核心文件被修改而产生冲突。
不需要修改数据库
整个关闭状态只存在于当前页面 JavaScript 内存。
因此不会增加:
- 数据库字段;
- Cookie;
- 用户设置;
- 服务端 Session。
不影响原有上传功能
弹窗只是一个前端提示层。
用户点击:
知道了
之后:
弹窗消失
↓
上传页面恢复正常
↓
游客仍然可以上传
它不会修改上传按钮,也不会修改上传接口。
二十一、最终实现总结
整个功能实际上由四个核心模块组成:
① 页面判断
↓
判断是否为 /upload
② 登录状态判断
↓
判断是否存在 #form-logout
③ 当前页面关闭状态
↓
noticeDismissed
④ 动态创建弹窗
↓
document.createElement()
最终形成:
游客
│
▼
访问 /upload
│
▼
不是排除页面
│
▼
没有登录
│
▼
当前页面没有关闭过
│
▼
显示游客提示
│
├── 登录 → /login
│
├── 注册 → /signup
│
└── 知道了 → 当前页面关闭
│
▼
刷新页面
│
▼
再次显示
这种实现方式简单、独立,而且不需要修改 Chevereto 核心程序,比较适合通过后台自定义 JavaScript实现网站前端功能增强。
总结
本教程实现的核心并不是单纯制作一个弹窗,而是建立了一套完整的**“页面 + 用户身份 + 当前访问状态”三重判断机制**:
页面必须正确
+
用户必须是游客
+
当前访问期间没有关闭过
=
显示提示
这样既能够向游客明确说明文件保存规则,又不会反复打扰已经登录的用户,同时也不会让“知道了”变成永久性的关闭设置。
对于允许游客上传文件的图片、视频托管站来说,这种方式能够在用户体验和规则提示之间取得比较好的平衡。













暂无评论内容