【JSON2WEB】10 基于 Amis 做个登录页面login.html
【JSON2WEB】01 WEB管理信息系统架构设计
【JSON2WEB】02 JSON2WEB初步UI设计
【JSON2WEB】03 go的模板包html/template的使用
【JSON2WEB】04 amis低代码前端框架介绍
【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成
【JSON2WEB】06 JSON2WEB前端框架搭建
【JSON2WEB】07 Amis可视化设计器CRUD增删改查
【JSON2WEB】08 Amis的事件和校验
【JSON2WEB】09 Amis-editor的代码移植到json2web
基于 Amis 做个登录页面 login.html ,用于验证用户名和密码的,验证成功后返回token,并保存token在 localStorage中。
参考视频教程,https://www.bilibili.com/video/BV1wu411Q7y3/?spm_id_from=333.788 ,Amis官方也没有视频教程,没有一点基础学起来很费劲啊。
1 创建登录页面 Login.html
1 新建登录页面
从官方文档 https://aisuda.bce.baidu.com/amis/zh-CN/docs/start/getting-started 拷贝hello.html,并修改后代码如下:
<!DOCTYPE html>
<html lang="zh"><head><meta charset="UTF-8" /><title>amis demo</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" /><meta http-equiv="X-UA-Compatible" content="IE=Edge" /><link rel="stylesheet" href="/sdk/sdk.css" /><link rel="stylesheet" href="/sdk/helper.css" /><link rel="stylesheet" href="/sdk/iconfont.css" /><!-- 这是默认主题所需的,如果是其他主题则不需要 --><!-- 从 1.1.0 开始 sdk.css 将不支持 IE 11,如果要支持 IE11 请引用这个 css,并把前面那个删了 --><!-- <link rel="stylesheet" href="sdk-ie11.css" /> --><!-- 不过 amis 开发团队几乎没测试过 IE 11 下的效果,所以可能有细节功能用不了,如果发现请报 issue --><style>html,body,.app-wrapper {position: relative;width: 100%;height: 100%;margin: 0;padding: 0;}</style>
</head><body><div id="root" class="app-wrapper"></div><script src="/sdk/sdk.js"></script><script type="text/javascript">(function () {let amis = amisRequire('amis/embed');// 通过替换下面这个配置来生成不同页面let amisJSON = {type: 'page',title: '登录JSON2WEB',body: {type: 'form',title: '',mode: 'horizontal',api: {url: 'http://127.0.0.1:5217/token/generate-token?userid=$userId&passwd=$passWd',method: 'post',adaptor: function (payload) {console.log(payload);if (payload.status === 0) {localStorage.setItem('token', payload.data.token);// localStorage.clear(); location.href = '/login.html';return payload;}}},redirect: '/index.html',body: [{label: '用户名:',type: 'input-text',name: 'userId'},{label: '密码:',type: 'input-password',name: 'passWd'}]}};let amisScoped = amis.embed('#root', amisJSON);})();</script>
</body></html>
1.2 核心就是 API的配置
1.3 页面预览
2 主页 index.html的代码
2.1 所有的API请求都带上token
token放在请求头里的Authorization,请求适配器代码如下:
requestAdaptor(api) {// Api前缀// if (api.url.indexOf("pages") == -1){// api.url = "http://127.0.0.1:5217" + api.url;// }//api.url = "http://127.0.0.1:5217" + api.url;// token 认证 // api.headers['Authorization'] = "Bearer " + localStorage.getItem('token');api.headers['Authorization'] = localStorage.getItem('token');console.log("全局请求适配器", api);return api;},
2.2 所有的响应适配器
也就是没有token或过期等都请求不到后台的数据,代码如下:
// 全局 api 适配器。// 另外在 amis 配置项中的 api 也可以配置适配器,针对某个特定接口单独处理。responseAdaptor(payload, response) {console.log("全局响应适配器", response);if (response.state == 401) {localStorage.clear();location.href = '/';}return payload, response;},
2.3 退出代码
退出时清空token并跳转到登录页,用内嵌js代码实现如下?
header: {type: 'tpl',inline: false,className: 'w-full',tpl: `<div class="flex justify-between"><div>顶部区域左侧</div><div><a href="#" οnclick="localStorage.clear(); location.href = '/';">退出</a></div></div>`},
2.4 首页全部代码
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>amis admin</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" /><meta http-equiv="X-UA-Compatible" content="IE=Edge" /><!-- <link rel="stylesheet" title="default" href="https://cdn.jsdelivr.net/npm/amis@beta/sdk/sdk.css" /><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/amis@beta/sdk/helper.css" /><script src="https://cdn.jsdelivr.net/npm/amis@beta/sdk/sdk.js"></script> --><link rel="stylesheet" title="default" href="/sdk/sdk.css" /><link rel="stylesheet" title="default" href="/sdk/antd.css" /><!-- <link rel="stylesheet" title="default" href="/sdk/cxd.css" /> --><link rel="stylesheet" href="/sdk/helper.css" /><script src="/sdk/sdk.js"></script><!-- <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> --><!-- <script src="https://cdn.jsdelivr.net/npm/history/umd/history.js"></script> --><script src="/sdk/history.js"></script><style>html,body,.app-wrapper {position: relative;width: 100%;height: 100%;margin: 0;padding: 0;}</style>
</head><body><div id="root" class="app-wrapper"></div><script>(function () {let amis = amisRequire('amis/embed');const match = amisRequire('path-to-regexp').match;// 如果想用 browserHistory 请切换下这处代码, 其他不用变//const history = History.createBrowserHistory();const history = History.createHashHistory();const app = {type: 'app',brandName: 'JSON2WEB',//logo: '/public/logo.png',logo: '/public/5217.jpg',header: {type: 'tpl',inline: false,className: 'w-full',tpl: `<div class="flex justify-between"><div>顶部区域左侧</div><div><a href="#" οnclick="localStorage.clear(); location.href = '/';">退出</a></div></div>`},// 如果想用 browserHistory 请切换下这处代码, 他不用变">退出登录</a></div></div>`footer: '<div class="p-2 text-center bg-light">版权没有,翻版不究!底部区域</div>',asideBefore: '<div class="p-2 text-center">菜单前面区域</div>',asideAfter: '<div class="p-2 text-center">菜单后面区域</div>',api: '/pages/site.json'};function normalizeLink(to, location = history.location) {to = to || '';if (to && to[0] === '#') {to = location.pathname + location.search + to;} else if (to && to[0] === '?') {to = location.pathname + to;}const idx = to.indexOf('?');const idx2 = to.indexOf('#');let pathname = ~idx? to.substring(0, idx): ~idx2? to.substring(0, idx2): to;let search = ~idx ? to.substring(idx, ~idx2 ? idx2 : undefined) : '';let hash = ~idx2 ? to.substring(idx2) : location.hash;if (!pathname) {pathname = location.pathname;} else if (pathname[0] != '/' && !/^https?\:\/\//.test(pathname)) {let relativeBase = location.pathname;const paths = relativeBase.split('/');paths.pop();let m;while ((m = /^\.\.?\//.exec(pathname))) {if (m[0] === '../') {paths.pop();}pathname = pathname.substring(m[0].length);}pathname = paths.concat(pathname).join('/');}return pathname + search + hash;}function isCurrentUrl(to, ctx) {if (!to) {return false;}const pathname = history.location.pathname;const link = normalizeLink(to, {...location,pathname,hash: ''});if (!~link.indexOf('http') && ~link.indexOf(':')) {let strict = ctx && ctx.strict;return match(link, {decode: decodeURIComponent,strict: typeof strict !== 'undefined' ? strict : true})(pathname);}return decodeURI(pathname) === link;}let amisInstance = amis.embed('#root',app,{location: history.location},{// watchRouteChange: fn => {// return history.listen(fn);// },requestAdaptor(api) {// Api前缀// if (api.url.indexOf("pages") == -1){// api.url = "http://127.0.0.1:5217" + api.url;// }//api.url = "http://127.0.0.1:5217" + api.url;// token 认证 // api.headers['Authorization'] = "Bearer " + localStorage.getItem('token');api.headers['Authorization'] = localStorage.getItem('token');console.log("全局请求适配器", api);return api;},// 全局 api 适配器。// 另外在 amis 配置项中的 api 也可以配置适配器,针对某个特定接口单独处理。responseAdaptor(payload, response) {console.log("全局响应适配器", response);if (response.state == 401) {localStorage.clear();location.href = '/';}return payload, response;},updateLocation: (location, replace) => {location = normalizeLink(location);if (location === 'goBack') {return history.goBack();} else if ((!/^https?\:\/\//.test(location) &&location ===history.location.pathname + history.location.search) ||location === history.location.href) {// 目标地址和当前地址一样,不处理,免得重复刷新return;} else if (/^https?\:\/\//.test(location) || !history) {return (window.location.href = location);}history[replace ? 'replace' : 'push'](location);},jumpTo: (to, action) => {if (to === 'goBack') {return history.goBack();}to = normalizeLink(to);if (isCurrentUrl(to)) {return;}if (action && action.actionType === 'url') {action.blank === false? (window.location.href = to): window.open(to, '_blank');return;} else if (action && action.blank) {window.open(to, '_blank');return;}if (/^https?:\/\//.test(to)) {window.location.href = to;} else if ((!/^https?\:\/\//.test(to) &&to === history.pathname + history.location.search) ||to === history.location.href) {// do nothing} else {history.push(to);}},isCurrentUrl: isCurrentUrl,// theme: 'cxd'theme: 'cxd'});history.listen(state => {amisInstance.updateProps({location: state.location || state});});})();</script>
</body></html>
3 后端REST2SQL修改
3.1 所有REST请求都要验证token
token从请求头Authorization获取。
switch req["RESTorSQL"] {case "REST":// token有效性验证tokenString := req["Authorization"].(string)if vToken(w, tokenString) != 200 {return}
token验证函数:
// token 验证函数
func vToken(w http.ResponseWriter, tokenString string) int {tokenmap := make(map[string]interface{})tokenmap = token.ValidateTokenHandler(w, tokenString)if tokenmap["status"] != http.StatusOK {// 抛出错误信息httpResWriter(w,tokenmap)return 401}return 200
}
主要内容就是抛出token错误信息,并设置返回代码为 401
4 nodejs路由配置
// 定义路由以加载不同的页面
app.get('/', (req, res) => {res.sendFile(path.resolve(__dirname, 'login.html'));
});app.get('/index.html', function (req, res) {res.sendFile(path.join(__dirname, 'index.html'));
});
http://localhost:3000/ 请求的就是登录页面 login.html
http://localhost:3000/index.html请求的是 index.html
5 实操演练
Step1 登录
http://localhost:3000/
Step 2 提交跳转
点【提交】按钮,登录成功跳转到主页index.html,可以查看token
Step 3 用户管理
可查询到信息,并可以crud操作。
Setp 4 退出
点主页右上角的【退出】按钮,可退出主页,并跳转到登录页,并清除了token
Step 5 直接在访问index.html
页面可以打开请求不到api的数据。
没有token或token过期都请求不到数据
脑子不好用,搞一点都记录一下,方便自己查询,好记性不如烂笔头。
本文完。
相关文章:

【JSON2WEB】10 基于 Amis 做个登录页面login.html
【JSON2WEB】01 WEB管理信息系统架构设计 【JSON2WEB】02 JSON2WEB初步UI设计 【JSON2WEB】03 go的模板包html/template的使用 【JSON2WEB】04 amis低代码前端框架介绍 【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成 【JSON2WEB】06 JSON2WEB前端框架搭建 【J…...

Android 你遇到的无障碍onGesture不执行
你是不是和我一样,在开发无障碍应用的时候,翻边了Android的AccessibilityService源码 但是就是发现不了onGesture不执行的原因? 你是不是和我一样,在好多测试手机之间徘徊,发现还是不执行? 你是不是和我一…...
Java学习10
目录 一.多态: 1.方法的多态: 2.对象的多态: 3.多态的注意事项与细节: 5.多态的应用: 二.Java的动态绑定机制: 三.多态应用: 1.多态数组: 2.多态参数: 三.Object类…...

第二十章 TypeScript(webpack构建ts+vue3项目)
构建项目目录 src-- main.ts-- App.vue--shim.d.tswebpack.config.jsindex.htmlpackage.jsontsconfig.json 基础构建 npm install webpack -D npm install webpack-dev-server -D npm install webpack-cli -D package.json 添加打包命令和 启动服务的命令 {"scripts…...

白酒:陈酿过程中的老熟度评价与品质提升方法
在豪迈白酒的酿造过程中,陈酿是一个至关重要的环节。陈酿不仅能使白酒老熟,提品质,还能发展出与众不同的风味和口感。云仓酒庄深知陈酿的重要性,并进行了深入的研究和实践。本文将探讨陈酿过程中的老熟度评价与品质提升方法。 首先…...

BoostSeacher
前言: 基于Boost库的搜索引擎 为何基于Boost库? 从技术上说:这个项目用了很多Boost库的接口从搜索引擎存储内说:存储的内容是Boost库的内容预期效果 预期效果:用户在浏览器输入关键词,浏览器显示相关结果 STEP1&#x…...
我的算法刷题笔记(3.18-3.22)
我的算法刷题笔记(3.18-3.22) 1. 螺旋矩阵1. total是总共走的步数2. int[][] directions {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};方位3. visited[row][column] true;用于判断是否走完一圈 2. 生命游戏1. 使用额外的状态22. 再复制一份数组 3. 旋转图像观…...

初探Ruby编程语言
文章目录 引言一、Ruby简史二、Ruby特性三、安装Ruby四、命令行执行Ruby五、Ruby的编程模型六、案例演示结语 引言 大家好,今天我们将一起探索一门历史悠久、充满魅力的编程语言——Ruby。Ruby是由松本行弘(Yukihiro Matsumoto)于1993年发明…...
深圳MES系统如何提高生产效率
深圳MES系统可以通过多种方式提高生产效率,具体如下: 实时监控和分析:MES系统可以实时收集并分析生产数据,帮助企业及时了解生产状况,发现问题并迅速解决,避免问题扩大化。这种实时监控和分析功能可以显著…...

QT常见Layout布局器使用
布局简介 为什么要布局?通过布局拖动不影响鼠标拖动窗口的效果等优点.QT设计器布局比较固定,不方便后期修改和维护;在Qt里面布局分为四个大类 : 盒子布局:QBoxLayout 网格布局:QGridLayout 表单布局&am…...

Elasticsearch8 - Docker安装Elasticsearch8.12.2
前言 最近在学习 ES,所以需要在服务器上装一个单节点的 ES 服务器环境:centos 7.9 安装 下载镜像 目前最新版本是 8.12.2 docker pull docker.elastic.co/elasticsearch/elasticsearch:8.12.2创建配置 新增配置文件 elasticsearch.yml http.host…...

还在为不知道怎么学习网络安全而烦恼吗?这篇文带你从入门级开始学习网络安全—认识网络安全
随着网络安全被列为国家安全战略的一部分,这个曾经细分的领域发展提速了不少,除了一些传统安全厂商以外,一些互联网大厂也都纷纷加码了在这一块的投入,随之而来的吸引了越来越多的新鲜血液不断涌入。 不同于Java、C/C等后端开发岗…...

DFS基础——迷宫
迷宫 配套视频讲解 关于dfs和bfs的区别讲解。 对于上图,假设我们要找从1到5的最短路,那么我们用dfs去找,并且按照编号从大到小的顺序去找,首先找到的路径如下, 从节点1出发,我们发现节点2可以走ÿ…...

iOS开发进阶(九):OC混合开发嵌套H5应用并互相通信
文章目录 一、前言二、嵌套H5应用并实现双方通信2.1 WKWebView 与JS 原生交互2.1.1 H5页面嵌套2.1.2 常用代理方法2.1.3 OC调用JS方法2.1.4 JS调用OC方法 2.2 JSCore 实现原生与H5交互2.2.1 OC调用H5方法并传参2.2.2 H5给OC传参 2.3 UIWebView的基本用法2.3.1 H5页面嵌套2.3.2 …...

新人应该从哪几个方面掌握大数据测试?
什么是大数据 大数据是指无法在一定时间范围内用传统的计算机技术进行处理的海量数据集。 对于大数据的测试则需要不同的工具、技术、框架来进行处理。 大数据的体量大、多样化和高速处理所涉及的数据生成、存储、检索和分析使得大数据工程师需要掌握极其高的技术功底。 需要你…...
linux debian运行pip报错ssl tsl module in Python is not available
写在前面 ① 在debian 8上升级了Python 3.8.5 ② 升级了openssl 1.1.1 问题描述 在运行pip命令时提示如下错误 pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.尝试了大神推荐的用如下方法重新编译安装python,发…...
宝塔设置限制ip后,ip改了之后 ,登陆不上了
前言 今天作死,在宝塔面板设置界面,将访问面板的ip地址限制成只有自己电脑的ip才能访问,修改之后直接人傻了,“403 forbidden”。吓得我直接网上一通搜索,还好,解决方法非常简单。 解决方法 打开ssh客户…...
解锁新功能,Dynadot现支持BITPAY平台虚拟货币
Dynadot现已支持虚拟货币付款!借助与BitPay平台的合作,Dynadot为您提供了多种安全的虚拟货币选择。我们深知每位客户都有自己偏好的支付方式,因此我们努力扩大了支付方式范围。如果您对这一新的支付方式感兴趣,在结账时您可以尝试…...
Android下的Touch事件分发详解
文章目录 一、事件传递路径二、触摸事件的三个关键方法2.1 dispatchTouchEvent(MotionEvent ev)2.2 onInterceptTouchEvent(MotionEvent ev)2.3 onTouchEvent(MotionEvent event) 三、ViewGroup中的dispatchTouchEvent实现四、总结 在Android系统中,触摸事件的分发和…...

uniapp的配置文件、入口文件、主组件、页面管理部分
pages.json 配置文件,全局页面路径配置,应用的状态栏、导航条、标题、窗口背景色设置等 main.js 入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如 vuex,注意uniapp无法使用vue-router,路由须在pag…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...