在静态文件 js/user上当下,的 auth.js 文件中

$(function () {
let $username = $('#user_name'); // 选择id为user_name的网页元素,需要定义一个id为user_name
let $img = $(".form-item .captcha-graph-img img"); // 获取图像标签
let sImageCodeId = ""; // 定义图像验证码ID值
let $mobile = $('#mobile'); // 选择id为mobile的网页元素,需要定义一个id为mobile
let $smsCodeBtn = $('.form-item .sms-captcha');// 获取短信验证码按钮元素,需要定义一个id为input_smscode
let $imgCodeText = $('#input_captcha'); // 获取用户输入的图片验证码元素,需要定义一个id为input_captcha
let $register = $('.form-contain'); // 获取注册表单元素 // 1、图片验证码逻辑
// 通过uuid生成验证码编号
// 拼接验证码地址
// 设置验证码图片标签的src
generateImageCode(); // 生成图像验证码图片
$img.click(generateImageCode); // 点击图片验证码生成新的图片验证码图片 // 2、用户名验证逻辑
$username.blur(function () {
fn_check_usrname();
}); // 3、手机号验证逻辑
// 判断用户手机号是否注册
$mobile.blur(function () {
fn_check_mobile();
}); // 4、发送短信验证码逻辑
$smsCodeBtn.click(function () {
// 判断手机号是否输入
if (fn_check_mobile() !== "success") {
return
} // 判断用户是否输入图片验证码
let text = $imgCodeText.val(); // 获取用户输入的图片验证码文本
if (!text) {
message.showError('请填写验证码!');
return
} if (!sImageCodeId) {
message.showError('图片UUID为空');
return
} // 正常
let SdataParams = {
"mobile": $mobile.val(), // 获取用户输入的手机号
"text": text, // 获取用户输入的图片验证码文本
"image_code_id": sImageCodeId // 获取图片UUID
}; // for test
// let SdataParams = {
// "mobile": "1806508", // 获取用户输入的手机号
// "text": "ha3d", // 获取用户输入的图片验证码文本
// "image_code_id": "680a5a66-d9e5-4c3c-b8ea" // 获取图片UUID
// }; // 向后端发送请求
$.ajax({
// 请求地址
url: "/sms_codes/",
// 请求方式
type: "POST",
// 向后端发送csrf token
// headers: {
// // 根据后端开启的CSRFProtect保护,cookie字段名固定为X-CSRFToken
// "X-CSRFToken": getCookie("csrf_token")
// },
// data: JSON.stringify(SdataParams),
data: JSON.stringify(SdataParams),
// 请求内容的数据类型(前端发给后端的格式)
contentType: "application/json; charset=utf-8",
// 响应数据的格式(后端返回给前端的格式)
dataType: "json",
async: false
})
.done(function (res) {
if (res.errno === "0") {
// 倒计时60秒,60秒后允许用户再次点击发送短信验证码的按钮
message.showSuccess('短信验证码发送成功');
let num = 60;
// 设置一个计时器
let t = setInterval(function () {
if (num === 1) {
// 如果计时器到最后, 清除计时器对象
clearInterval(t);
// 将点击获取验证码的按钮展示的文本恢复成原始文本
$smsCodeBtn.html("获取验证码");
} else {
num -= 1;
// 展示倒计时信息
$smsCodeBtn.html(num + "秒");
}
}, 1000);
} else {
message.showError(res.errmsg);
}
})
.fail(function(){
message.showError('服务器超时,请重试!');
}); }); // 5、注册逻辑
$register.submit(function (e) {
// 阻止默认提交操作
e.preventDefault(); // 获取用户输入的内容
let sUsername = $username.val(); // 获取用户输入的用户名字符串
let sPassword = $("input[name=password]").val();
let sPasswordRepeat = $("input[name=password_repeat]").val();
let sMobile = $mobile.val(); // 获取用户输入的手机号码字符串
let sSmsCode = $("input[name=sms_captcha]").val(); // 判断用户名是否已注册
if (fn_check_usrname() !== "success") {
return
} // 判断手机号是否为空,是否已注册
if (fn_check_mobile() !== "success") {
return
} // 判断用户输入的密码是否为空
if ((!sPassword) || (!sPasswordRepeat)) {
message.showError('密码或确认密码不能为空');
return
} // 判断用户输入的密码和确认密码长度是否为6-20位
if ((sPassword.length < 6 || sPassword.length > 20) ||
(sPasswordRepeat.length < 6 || sPasswordRepeat.length > 20)) {
message.showError('密码和确认密码的长度需在6~20位以内');
return
} // 判断用户输入的密码和确认密码是否一致
if (sPassword !== sPasswordRepeat) {
message.showError('密码和确认密码不一致');
return
} // 判断用户输入的短信验证码是否为6位数字
if (!(/^\d{6}$/).test(sSmsCode)) {
message.showError('短信验证码格式不正确,必须为6位数字!');
return
} // 发起注册请求
// 1、创建请求参数
let SdataParams = {
"username": sUsername,
"password": sPassword,
"password_repeat": sPasswordRepeat,
"mobile": sMobile,
"sms_code": sSmsCode
}; // 2、创建ajax请求
$.ajax({
// 请求地址
url: "/users/register/", // url尾部需要添加/
//url: "/users/res/", // url尾部需要添加/
// 请求方式
type: "POST",
data: JSON.stringify(SdataParams),
// 请求内容的数据类型(前端发给后端的格式)
contentType: "application/json; charset=utf-8",
// 响应数据的格式(后端返回给前端的格式)
dataType: "json",
})
.done(function (res) {
if (res.errno === "0") {
// 注册成功
message.showSuccess('恭喜你,注册成功!');
setTimeout(function () {
// 注册成功之后重定向到主页
//window.location.href = '/';
//重定向到原页面
window.location.href = document.referrer;
}, 1000)
} else {
// 注册失败,打印错误信息
message.showError(res.errmsg);
}
})
.fail(function(){
message.showError('服务器超时,请重试!');
}); }); // 生成一个图片验证码的编号,并设置页面中图片验证码img标签的src属性
function generateImageCode() {
// 1、生成一个图片验证码随机编号
sImageCodeId = generateUUID();
// 2、拼接请求url /image_codes/<uuid:image_code_id>/
let imageCodeUrl = "/image_codes/" + sImageCodeId + "/";
// 3、修改验证码图片src地址
$img.attr('src', imageCodeUrl) } // 生成图片UUID验证码
function generateUUID() {
let d = new Date().getTime();
if (window.performance && typeof window.performance.now === "function") {
d += performance.now(); //use high-precision timer if available
}
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
return uuid;
} // 判断用户名是否已经注册
function fn_check_usrname() {
let sUsername = $username.val(); // 获取用户名字符串
let sReturnValue = ""; if (sUsername === "") {
message.showError('用户名不能为空!');
return
} if (!(/^\w{5,20}$/).test(sUsername)) {
message.showError('请输入5-20个字符的用户名');
return
} // 发送ajax请求,去后端查询用户名是否存在
$.ajax({
url: '/usernames/' + sUsername + '/',
type: 'GET',
dataType: 'json',
async: false
})
.done(function (res) {
if (res.data.count !== 0) {
message.showError(res.data.username + '已注册,请重新输入!')
sReturnValue = ""
} else {
message.showInfo(res.data.username + '能正常使用!')
sReturnValue = "success"
}
})
.fail(function () {
message.showError('服务器超时,请重试!');
sReturnValue = ""
});
return sReturnValue
} // 判断手机号是否注册
function fn_check_mobile() {
let sMobile = $mobile.val(); // 获取用户输入的手机号码字符串
let sReturnValue = "";
if (sMobile === "") {
message.showError('手机号不能为空!');
return
}
if (!(/^1[345789]\d{9}$/).test(sMobile)) {
message.showError('手机号码格式不正确,请重新输入!');
return
} $.ajax({
url: '/mobiles/' + sMobile + '/',
type: 'GET',
dataType: 'json',
async: false
})
.done(function (res) {
if (res.data.count !== 0) {
message.showError(res.data.mobile + '已注册,请重新输入!')
sReturnValue = ""
} else {
message.showSuccess(res.data.mobile + '能正常使用!');
sReturnValue = "success"
}
})
.fail(function () {
message.showError('服务器超时,请重试!');
sReturnValue = ""
});
return sReturnValue } // get cookie using jQuery
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
let cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
} function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
} // Setting the token on the AJAX request
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
}); });

  

在静态文件下 js/user 目录下,的login.js文件中

/**
* Created by Administrator on 2018/12/15 0015.
*/
$(function () {
let $login = $('.form-contain'); // 获取登录表单元素 // for test
// console.log(document.referrer); // 将referrer url 打印到终端 // 登录逻辑
$login.submit(function (e) {
// 阻止默认提交操作
e.preventDefault(); // 获取用户输入的账号信息
let sUserAccount = $("input[name=telephone]").val(); // 获取用户输入的用户名或者手机号
// 判断用户输入的账号信息是否为空
if (sUserAccount === "") {
message.showError('用户账号不能为空');
return
}
// 判断输入手机号格式或者用户名格式是否正确
if (!(/^\w{5,20}$/).test(sUserAccount) || !(/^\w{5,20}$/).test(sUserAccount)) {
message.showError('请输入合法的用户账号:5-20个字符的用户名或者11位手机号');
return
} // 获取用户输入的密码
let sPassword = $("input[name=password]").val(); // 获取用户输入的密码
// 判断用户输入的密码是否为空
if (!sPassword) {
message.showError('密码不能为空');
return
}
// 判断用户输入的密码是否为6-20位
if (sPassword.length < 6 || sPassword.length > 20) {
message.showError('密码的长度需在6~20位以内');
return
} // 获取用户是否勾许"记住我",勾许为true,不勾许为false
let bStatus = $("input[type='checkbox']").is(":checked"); // 获取用户是否选择记住我,勾上代表true,没勾上代码false // 发起登录请求
// 创建请求参数
let SdataParams = {
"user_account": sUserAccount,
"password": sPassword,
"remember_me": bStatus
}; // 创建ajax请求
$.ajax({
// 请求地址
url: "/users/login/", // url尾部需要添加/
// 请求方式
type: "POST",
data: JSON.stringify(SdataParams),
// 请求内容的数据类型(前端发给后端的格式)
contentType: "application/json; charset=utf-8",
// 响应数据的格式(后端返回给前端的格式)
dataType: "json",
})
.done(function (res) {
if (res.errno === "0") {
// 注册成功
message.showSuccess('恭喜你,登录成功!');
setTimeout(function () {
// 注册成功之后重定向到打开登录页面之前的页面
window.location.href = document.referrer;
}, 1000)
} else {
// 登录失败,打印错误信息
message.showError(res.errmsg);
}
})
.fail(function(){
message.showError('服务器超时,请重试!');
});
}); // get cookie using jQuery
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
let cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
} function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
} // Setting the token on the AJAX request
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
}); });

  

在 html 文件中要引入对应 js 文件,级标签的对名称 ,

潭州课堂25班:Ph201805201 django 项目 第十八课 前台 注解 (课堂笔记)的更多相关文章

  1. 潭州课堂25班:Ph201805201 django 项目 第二十八课 新闻elasticsearch搜索前后功台能实现 (课堂笔记)

    后端功能实现 文件,类,字段,命名不要改动, 在apps/news/search_indexes.py中创建如下类:(名称固定为search_indexes.py) # -*-# -*- coding ...

  2. 潭州课堂25班:Ph201805201 django 项目 第二十六课 docker简介 (课堂笔记)

    官方文档: https://docs.docker.com/install/linux/docker-ce/ubuntu/#set-up-the-repository 1,更新下sudo apt-ge ...

  3. 潭州课堂25班:Ph201805201 django 项目 第二十九课 docker实例,文件下载前后台实现 (课堂笔记)

    docker 实例 :wq!保存退出 放入一个 html 文件 权限不够,加 sudo 查看本地仓库的 image 运行 docker -- name,后跟个运行名, -p 物理机端口映射到容器端口, ...

  4. 潭州课堂25班:Ph201805201 django 项目 第十五课 用户注册功能后台实现 (课堂笔记)

    前台:判断用户输入 ,确认密码,手机号, 一切通过后向后台发送请求, 请求方式:post 在 suers 应用下的视图中: 1,创建个类, 2,创建 GET 方法,宣言页面 3,创建  POST 方法 ...

  5. 潭州课堂25班:Ph201805201 django 项目 第二十五课 文章多级评论前后台实现 (课堂笔记)

    添加新闻评论功能 1.分析 业务处理流程: 判断前端传的新闻id是否为空,是否为整数.是否不存在 判断评论的内容是否为空 判断是否有父评论,父评论的id是否与新闻id匹配 判断用户是否登录 保存新闻评 ...

  6. 潭州课堂25班:Ph201805201 django 项目 第二十四课 文章主页 多级评论数据库设计 ,后台代码完成 (课堂笔记)

    加载新闻评论功能 1.分析 业务处理流程: 判断前端传的新闻id是否为空,是否为整数.是否不存在 请求方法:GET url定义:'/news/<int:news_id>' 请求参数:url ...

  7. 潭州课堂25班:Ph201805201 django 项目 第二十二课 文章主页 新闻列表页面滚动加载,轮播图后台实现 (课堂笔记)

    新建static/js/news/index.js文件 ,主要用于向后台发送请求, // 新建static/js/news/index.js文件 $(function () { // 新闻列表功能 l ...

  8. 潭州课堂25班:Ph201805201 django 项目 第十九课 文章主页数据库模型,前后台功能实现 (课堂笔记)

    -数据库模型设计 : 文章:新闻表: 字段:图片,标题,摘要,类型,作者,创建时间 标签表 评论表, 轮播图:外键,指向文章的外键表 在 utls 目录下创建 models.py  把其它模型常用的字 ...

  9. 潭州课堂25班:Ph201805201 django 项目 第三十一课 在线课堂视频点播的实现(课堂笔记)

    在线课堂 一.数据库模型设计 # 在apps/course/models.py中定义如下模型: from django.db import models from utils.models impor ...

随机推荐

  1. 微信录音文件上传到服务器以及amr转化成MP3格式,linux上转换简单方法

    微信公众号音频接口开发 根据业务需求,我们可能需要将微信录音保存到服务器,而通过微信上传语音接口上传到微信服务器的语音文件的有效期只有3天,所以需要将文件下载到我们自己的服务器. 上传语音接口 wx. ...

  2. BZOJ 2818 Gcd(欧拉函数+质数筛选)

    2818: Gcd Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 9108  Solved: 4066 [Submit][Status][Discu ...

  3. Centos7+ASP.Net Core 运行

    一:ASP.Net Core跨平台运行,需要在Linux安装运行环境.本机器使用的Centos,下载安装地址为:https://www.microsoft.com/net/core#centos su ...

  4. AspNetCore MVC + Vue.Js 项目搭建

    1.准备 全文重点在于搭建环境,其他相关知识点请百度. VS2017 升级到最新的版本 安装 net core 2.0 安装 npm (npm相关使用请百度或咨询前端小伙伴) 全局安装 webpack ...

  5. Windows Phone MultiBinding :Cimbalino Toolkit

    在WPF和WIN8中是支持MultiBinding 这个有啥用呢,引用下MSDN的例子http://msdn.microsoft.com/en-us/library/system.windows.da ...

  6. [转] 跨域资源共享 CORS 详解

    CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...

  7. Oracle 11g 安装过程中“检查网络配置要求 未执行”解决方法

    正在检查网络配置要求... 检查完成.此次检查的总体结果为: 未执行 网上查了一下,很多朋友都遇到这个问题而无从下手,其实解决起来很容易的. 只需要在 Windows XP 中安装 Microsoft ...

  8. Python3爬虫知识点总结

    1.requests获取响应头的方法 eg:获取响应头信息 import requests res = request.head(url).headers print(res)

  9. L3-021 神坛 (30 分) 计算几何

    在古老的迈瑞城,巍然屹立着 n 块神石.长老们商议,选取 3 块神石围成一个神坛.因为神坛的能量强度与它的面积成反比,因此神坛的面积越小越好.特殊地,如果有两块神石坐标相同,或者三块神石共线,神坛的面 ...

  10. URL简介

    一般来说,http请求都会和URL地址有关,那么今天就来说说URL的组成部分. 实例:http://192.168.1.12/phpwind/searcher.php?keyword=phpwind& ...