Ajax — 大事件项目(第三天)

大事件-03

用户信息

表单验证

html中,直接使用layui提供的内置验证规则 email

<input type="text" name="email" required lay-verify="required|email" placeholder="请输入邮箱" autocomplete="off" class="layui-input">

重置表单

// ------------------   重置表单 --------------------
// 重置的时候,并不是清空输入框的值,而是恢复默认的样子
$('button[type="reset"]').on('click', function (e) {e.preventDefault();renderForm(); // 调用函数,从新发送ajax请求,获取用户信息,从新为表单赋值
});

关于base64格式的图片说明

  • base64格式只是图片的一种格式,用字符串表示图片的格式
  • base64格式的优点:减少http请求,加快小图片的响应速度
  • base64格式的缺点:体积比正常图片大 30% 左右。

https://www.css-js.com/tools/base64.html

优化JS

新建 /assets/js/common.js。代码如下:

$(function () {// 修改和配置ajax选项$.ajaxPrefilter(function (options) {console.log(options);// 修改url// options.url ====  /my/userinfooptions.url = 'http://www.liulongbin.top:3007' + options.url;// 以 /my 开头的url需要设置headers// if (options.url.indexOf('/my') > -1) {if (options.url.includes('/my')) {options.headers = {Authorization: localStorage.getItem('token')}}/*** options = {*    type: 'xxx',*    url: xxxxx*    .....* }*/});
})
  • 其他HTML页面,引入common.js文件

    • 注意引入的位置(在jQuery之后,在自己的js之前)
  • 修改原来的JS。

    • 去掉 http://www.liulongbin.top:3007 (查找替换比较快、一个一个改也行)
    • 去掉headers

没有登录不能访问有权限的接口

在common.js 开头的位置,加入一个判断

如果没有token,并且地址栏的url也不是login.html 。说明没有登录,还想看其他页面,不允许,直接跳转到登录页面。


//  common.js
// 判断。如果没有token,直接退出到 /login.html 
// 不要放到入口函数里面,需要代码执行到common.js,马上就执行代码
// 请求的路径不是login.html  并且 还没有token,那么就跳转到 /login.html
if (!localStorage.getItem('token') && !location.href.includes('/login.html')) {location.href = '/login.html';
}

测试的时候,注意看一下token有没有。

上述判断,对于大多数用户,没有问题。

如果,一个懂得编程的人,手动加了一个假token,则上述判断就会失效。解决办法是,ajax请求之后,根据接口返回的结果,再次判断用户是否是真的登录了,如果没有登录,则跳转到登录页面。

// $.ajaxPrefilter() 函数内部
// 配置complete函数。ajax请求完成(不管成功还是失败)都会触发的一个函数
options.complete = function (xhr) {// xhr.responseJSON 表示服务器返回的结果// console.log(xhr);if (xhr.responseJSON.status === 1 && xhr.responseJSON.message === '身份认证失败!') {// 满足条件,说明用户没有登录,而且还访问了需要验证的接口// 清除假tokenlocalStorage.removeItem('token');// 跳转到登录页面location.href = '/login.html';}
}

更新密码

准备工作

  • 创建所需的HTML、css、js文件
  • 首页侧边栏和头部区域挂好链接
  • 加载好所需的css和js文件

页面布局

  • html,去复制 userinfo.html

  • css,去复制 userinfo.css

  • HTML自行修改

    • type类型
    • 去掉readonly

表单验证

let form = layui.form;
// --------------- 表单验证 -----------------
form.verify({// key: value// 验证规则: []// 验证规则: function// 验证长度 6~12位len: [/^\S{6,12}$/, '长度必须6到12位,不能有空格'],  // {6,12}不能出现空格// 验证新密码不能和原密码相同diff: function (value) {// value 表示新密码// 获取原密码let oldPwd = $('.oldPwd').val();if (value === oldPwd) {return '新密码不能和原密码相同';}},// 验证两次新密码必须相同same: function (value) {// value 表示确认密码// 获取新密码let newPwd = $('.newPwd').val();if (newPwd !== value) {return '两次密码不一致';}}
});
  • 三个密码框,都使用len这个验证规则
  • 新密码,使用diff,这个验证规则
  • 确认密码,使用 same 验证规则

自行给原密码(oldPwd)和新密码(newPwd)加一个 类

ajax请求,完成更新

// -------------- ajax请求,完成更新 ---------
$('form').on('submit', function (e) {e.preventDefault();// 获取表单中的数据,ajax提交$.ajax({type: 'POST',url: '/my/updatepwd',data: $(this).serialize(), // 一定要检查表单各项的name属性;用layui的表单取值也可以success: function (res) {// console.log(res);layer.msg(res.message);if (res.status === 0) {// 重置输入框$('button[type="reset"]').click();}                }});
})

更换头像

准备工作

  • 创建 /user/avatar.html 、创建 /assets/css/user/avatar.css 创建/assets/js/user/avatar.js

  • 侧边栏和头部区域挂好超链接

  • html中引入所需的css和js文件

<!-- 加载layui.css -->
<link rel="stylesheet" href="/assets/lib/layui/css/layui.css">
<!-- 加载cropper.css -->
<link rel="stylesheet" href="/assets/lib/cropper/cropper.css">
<!-- 加载自己的css -->
<link rel="stylesheet" href="/assets/css/user/avatar.css">
<!-- 加载jQuery -->
<script src="/assets/lib/jquery.js"></script>
<!-- 按顺序 加载Cropper.js -->
<script src="/assets/lib/cropper/Cropper.js"></script>
<!-- 按顺序 jquery-cropper.js -->
<script src="/assets/lib/cropper/jquery-cropper.js"></script>
<!-- 加载layui.all.js -->
<script src="/assets/lib/layui/layui.all.js"></script>
<!-- 加载common -->
<script src="/assets/js/common.js"></script>
<!-- 加载repwd -->
<script src="/assets/js/user/avatar.js"></script>

复制HTML和CSS(完成布局)

完成后的效果:

在这里插入图片描述

点击按钮,可选择图片

  • html中加入一个隐藏的文件域
  • 点击上传按钮的时候,触发文件域的单击事件
<!-- 加一个隐藏的文件域 -->
<input type="file" id="file" style="display: none;" accept="image/*">
<button type="button" class="layui-btn" id="chooseImage">上传</button>
// -------------  点击  上传  ,可以选择图片  ------------
$('#chooseImage').click(function () {$('#file').click();
});

创建剪裁区

  • 使用插件 cropper ,提供的方法,实现剪裁区的创建
  • 具体做法:
    • 找到剪裁区的图片 (img#image)
    • 设置配置项
    • 调用cropper方法,创建剪裁区
// ---------------  创建剪裁区 ------------------
// - 找到剪裁区的图片 (img#image)
let image = $('#image');
// - 设置配置项
let option = {// 纵横比(宽高比)aspectRatio: 1, // 正方形// 指定预览区域preview: '.img-preview' // 指定预览区的类名(选择器)
};
// - 调用cropper方法,创建剪裁区
image.cropper(option);

更换图片,重置剪裁区

  • 找到选择的文件(文件对象)
  • 为文件对象创建一个临时的url
  • 更换剪裁区的图片
    • 先销毁原来的剪裁区
    • 更改图片的src属性
    • 重新生成剪裁区
// --------------  更换剪裁区的图片 ---------------
// 当文件域的内容改变的时候,更换图片
$('#file').change(function () {// console.log(111);// 1. 找到选择的图片(文件对象)// console.dir(this);let fileObj = this.files[0]; // 我们选择的图片的文件对象// 2. 根据文件对象,生成一个临时的url,用于访问被选择的图片let url = URL.createObjectURL(fileObj);// console.log(url);// 3. 更换剪裁区的图片的src属性// - 销毁原理的剪裁区// - 更换图片// - 重新创建剪裁区image.cropper('destroy').attr('src', url).cropper(option);
});

点击保存,实现剪裁并修改头像

  • 调用 cropper 方法,传递 getCroppedCanvas 参数,得到一个canvas图片(对象)
  • 调用canvas的toDataURL()方法,得到base64格式的图片
  • ajax提交即可
// ---------------  点击 确定 的时候,剪裁图片,转成base64格式,提交字符串到接口 ----------
$('#sure').click(function () {// 剪裁得到一张图片(canvas图片)let i = image.cropper('getCroppedCanvas', { // 创建一个 Canvas 画布width: 100,height: 100});// 把图片转成base64格式let str = i.toDataURL(); // 把canvas图片转成base64格式// console.log(str); // base64格式的字符串// ajax提交字符串给接口$.ajax({type: 'POST',url: '/my/update/avatar',data: {avatar: str},success: function (res) {layer.msg(res.message);if (res.status === 0) {// 更换成功,调用父页面的 getUserInfo() ,重新渲染头像window.parent.getUserInfo();}}});
});

合并user分支,创建article分支

# 提交当前 user 分支所有的代码
# 切换到master
git checkout master# 合并 user 到 master
git merge user# 创建并切换到article 分支
git checkout -b article

类别列表

准备工作

  • 创建文件
    • /article/category.html
    • /assets/css/article/category.css
    • /assets/js/article/category.js
  • 侧边栏挂超链接
  • 加载所需的css和js

页面布局

<body><div class="layui-card"><div class="layui-card-header">文章管理<button type="button" class="layui-btn  layui-btn-normal layui-btn-sm">添加类别</button></div><div class="layui-card-body"><!-- 内容区 --><table class="layui-table"><colgroup><col width="35%"><col width="35%"><col></colgroup><thead><tr><th>类别名称</th><th>类别别名</th><th>操作</th></tr> </thead><tbody><!-- 模板引擎遍历出来的内容 --></tbody></table></div></div><script type="text/html" id="list">{{each data val}}<tr><td>{{val.name}}</td><td>{{val.alias}}</td><td><button type="button" class="layui-btn  layui-btn-xs">编辑</button><button type="button" class="layui-btn layui-btn  layui-btn-danger  layui-btn-xs">删除</button></td></tr>{{/each}}</script>
</body>

模板引擎渲染页面

$(function(){//------------------------ajax请求列表-----------------------renderHtml();function renderHtml(){$.ajax({url: '/my/article/cates',success:function(res){// console.log(res);//    if(res.status === 0){let str = template('list',res);// console.log(str);//把最终的结果放在tbody中去$('tbody').html(str);//    }},});}
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/248023.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iOS运行时-使用Runtime向Category中添加属性以及运行时介绍

前言 了解OC的都应该知道&#xff0c;在一般情况下&#xff0c;我们是不能向Category中添加属性的&#xff0c;只能添加方法&#xff0c;但有些情况向&#xff0c;我们确实需要向Category中添加属性&#xff0c;而且很多系统的API也有一些在Category添加属性的情况&#xff0c;…

Git图形化管理工具

Git图形化管理工具 注意&#xff1a;必须在创建的仓库中进行右键打开 复制这段内容后打开百度网盘App&#xff0c;操作更方便哦。 链接&#xff1a;https://pan.baidu.com/s/1eXIk01LXSmzmXvYfw3MnEA 提取码&#xff1a;J166 --来自百度网盘超级会员V5的分享 分类 sourceTr…

TCP/IP(一):数据链路层

背景 这一系列的文章主要是为一般的、非专业开发岗位(如移动端)的工程师准备&#xff0c;一方面可以对网络的基本知识有基本的了解&#xff0c;另一方面不至于面试中被问到相关问题时束手无策。知识以 TCP/IP 协议簇为主&#xff0c;也会有应用层和数据链路层的简单介绍。 文…

Linux系统编程——线程(1)

目录 线程概要Linux内核线程实现原理线程的共享/不共享资源线程优缺点线程控制原语pthread_selfpthread_createpthread_exitpthread_joinpthread_cancel终止线程方式控制原语对比前情提要&#xff1a; Linux用户级线程和内核级线程区别 线程概要 Linux内核线程实现原理 类Unix系…

TCP/IP(二):IP协议

IP协议处于OSI参考模型的第三层——网络层&#xff0c;网络层的主要作用是实现终端节点间的通信。IP协议是网络层的一个重要协议&#xff0c;网络层中还有ARP(获取MAC地址)和ICMP协议(数据发送异常通知) 数据链路层的作用在于实现同一种数据链路下的包传递&#xff0c;而网络层…

Ajax — 大事件项目(第四天)

分类管理 添加分类 初步使用弹出层 给 “添加分类” 绑定一个单击事件单击事件中&#xff0c;使用 layer.open() 实现一个弹出层 type: 1, 弹层的类型是页面层title, “添加文字分类”content: ‘字符串&#xff0c;DOM’,area: [‘500px’, ‘250px’] // ---------------…

redis学习(四)

一、Redis 键(key) 1、Redis 键命令用于管理 redis 的键。 2、Redis 键命令的基本语法如下&#xff1a;redis 127.0.0.1:6379> COMMAND KEY_NAME 3、常用key命令 keys * 获取所有的keyselect 0 选择第一个库move myString 1 将当前的数据库key移动到某个…

TCP/IP(三):IP协议相关技术

在前两篇文章中&#xff0c;我分别介绍了数据链路层和网络层的IP协议。虽然这个系列教程的重点是搞定 TCP/IP&#xff0c;不过不用着急&#xff0c;本文简要介绍完与 IP 协议相关的技术&#xff0c;下一篇文章就会正式、详细的介绍 传输层与 TCP 协议。这篇文章会介绍 DNS、ARP…

Node — 第一天

Node-01 会 JavaScript&#xff0c;就能学会 Node.js&#xff01;&#xff01;&#xff01; **Node.js 的官网地址&#xff1a; ** Node.js 的学习路径&#xff1a; JavaScript 基础语法 Node.js 内置 API 模块&#xff08;fs、path、http等&#xff09; 第三方 API 模块&…

TCP/IP(四):TCP 与 UDP 协议简介

从本章开始&#xff0c;我们开始介绍最重要的传输层。传输层位于 OSI 七层模型的第四层&#xff08;由下往上&#xff09;。顾名思义&#xff0c;传输层的主要作用是实现应用程序之间的通信。网络层主要是保证不同数据链路下数据的可达性&#xff0c;至于如何传输数据则是由传输…

Node — 第二天

http模块 搭建服务器的步骤 ① 导入 http 模块 ② 创建 web 服务器实例 ③ 为服务器实例绑定 request 事件&#xff0c;监听客户端的请求 ④ 启动服务器 // ① 导入 http 模块 const http require(http);// ② 创建 web 服务器实例 const server http.createServer();/…

TCP/IP(五):TCP 协议详解

上一节 中讲过&#xff0c;TCP 协议是面向有连接的协议&#xff0c;它具有丢包重发和流量控制的功能&#xff0c;这是它区别于 UDP 协议最大的特点。本文就主要讨论这两个功能。 数据包重发 数据发送 丢包重发的前提是发送方能够知道接收方是否成功的接收了消息。所以&#…

TCP/IP(六):HTTP 与 HTTPS 简介

本文是准备面试过程中网络部分总结整理的最后一篇文章&#xff0c;主要介绍以下知识&#xff1a; HTTP 协议概述POST 请求和 GET 请求Cookie 和 Session数据传输时的加密HTTPS 简介 HTTP 协议 在 OSI 七层模型中&#xff0c;HTTP 协议位于最顶层的应用层中。通过浏览器访问网…

Node — 第三天

模块化 什么是模块化 模块化是指解决一个复杂问题时&#xff0c;自顶向下逐层把系统划分成若干模块的过程。 对于整个系统来说&#xff0c;模块是可组合、分解和更换的单元。 生活中的模块化 编程中的模块化 编程领域中的模块化&#xff0c;就是遵守固定的规则&#xff0c;…

FireDAC 中文字段过滤问题

当使用 FireDAC Filter 过滤数据的时候&#xff0c;通常这样写&#xff1a; FDMemTable.Filtered : False; FDMemTable1.Filter : 姓名 string(edtFilter.Text).QuotedString; FDMemTable.Filtered : True; 将会报错&#xff1a;[FireDAC][Stan][Eval]-107. Invalid characte…

Express — 使用步骤

Express Express 介绍安装搭建服务器的步骤express提供的新方法GET接口 获取GET中的请求参数 POST接口 获取POST请求提交的数据 中间件原理中间件语法中间件初体验&#xff08;设置响应头&#xff09;中间件开放静态资源中间件接收POST请求体中间件返回404页面 express 介绍 E…

大模型工具_Langchain-Chatchat

https://github.com/chatchat-space/Langchain-Chatchat 原Langchain-ChatGLM 1 功能 整体功能&#xff0c;想解决什么问题 基于 Langchain 与 ChatGLM 等LLM模型&#xff0c;搭建一套针对中文场景与开源模型&#xff0c;界面友好、可离线运行的知识库问答解决方案。 当前解决…

iOS 键盘风格详解UIKeyboardType

一、键盘风格 UIKit框架支持8种风格键盘。 [java] view plaincopy print?typedef enum { UIKeyboardTypeDefault, // 默认键盘&#xff1a;支持所有字符 UIKeyboardTypeASCIICapable, // 支持ASCII的默认键盘 UIKeyboardTypeNu…

Node — 第四天(Promise与路由)

Promise - ES6新对象 Promise能够处理异步程序。 回调地狱 JS中或node中&#xff0c;都大量的使用了回调函数进行异步操作&#xff0c;而异步操作什么时候返回结果是不可控的&#xff0c;如果我们希望几个异步请求按照顺序来执行&#xff0c;那么就需要将这些异步操作嵌套起来…

winform datagridview控件使用

最近做项目时&#xff0c;显示查询结果总需要绑定到datagridview控件上显示&#xff0c;总结了给datagridview绑定数据的方式&#xff0c;以及导出datagridview数据到excel表格&#xff0c;如有错误请多指教 1.直接绑定数据源&#xff0c;可以绑定的数据格式有List<T>,Da…