【毕业设计】前后端分离——实现登录注册功能

news2024/11/27 5:32:58

🌈据说,看我文章时 关注、点赞、收藏帅哥美女们 心情都会不自觉的好起来。

前言:
🧡作者简介:大家好我是 user_from_future ,意思是 “ 来自未来的用户 ” ,寓意着未来的自己一定很棒~
✨个人主页:点我直达,在这里肯定能找到你想要的~
👍专栏介绍:个人记账分析系统 ,专门记录制作过程,每天进步一点点~

想看往期历史文章,可以浏览此博文: 历史文章目录,后续所有文章发布都会同步更新此博文~

人生苦短,我用python

前后端分离——实现登录注册功能

  • 后端部分
    • 登录视图
    • 注册视图
    • 图形验证码视图
    • 邮件验证码视图
    • 服务器时间视图
    • 路由部分
  • 前端部分
    • 定义的路由
    • 文件 App.vue
    • 文件 Home.vue
    • 文件 Login.vue
    • 文件 Register.vue
    • 效果
  • 总结

后端部分

下文出现的 payment 是我创建的 app ,使用 django-admin startapp payment 创建,此项目设计为前后端完全分离,通过 {'code': 0, 'msg': 'str', 'data': object} 传递信息,data 可以省略。

登录视图

文件 payment\views.py

def login_(request):
    if request.method == 'POST':
        username = loads(request.body)['username']
        password = loads(request.body)['password']
        user = User.objects.filter(username=username) or User.objects.filter(email=username)
        if user:
            user = authenticate(username=user[0].username, password=password)
            if user:
                if user.is_active:
                    login(request, user)
                    Setting.objects.create(last_ip=request.META['REMOTE_ADDR'], owner=user)
                    request.session['uname'] = user.username
                    request.session['admin'] = user.is_superuser
                    response = JsonResponse({'code': 0, 'msg': '登录成功!'})
                    response.set_cookie('uname', user.username)
                    return response
                return JsonResponse({'code': -1, 'msg': '用户状态不可用!'})
            return JsonResponse({'code': -2, 'msg': '用户名密码错误!'})
        return JsonResponse({'code': -3, 'msg': '用户名不存在!'})
    return JsonResponse({'code': 1, 'msg': '请求方法只能是POST方法!'})

注册视图

文件 payment\views.py

def register(request):
    if request.method == 'POST':
        username = loads(request.body)['username']
        password = loads(request.body)['password']
        email = loads(request.body)['email']
        yzm = loads(request.body)['yzm']
        if User.objects.filter(username=username):
            return JsonResponse({'code': -1, 'msg': '用户名已存在!'})
        if request.session.get('email') != email or request.session.get('yzm') != yzm:
            return JsonResponse({'code': -2, 'msg': '邮箱验证码错误!'})
        user = User.objects.create_user(username=username, password=password, email=email)
        if user.username:
            return JsonResponse({'code': 0, 'msg': '注册成功!'})
        return JsonResponse({'code': -3, 'msg': '注册失败!请重新尝试注册!'})
    return JsonResponse({'code': 1, 'msg': '请求方法只能是POST方法!'})

图形验证码视图

文件 PersonalAccountWeb\views.py
图形验证码就由前端校验,简单通过 base64 加密验证码字符串。

def verification_code(request):
    image = ImageCaptcha()
    # 获得随机生成的验证码
    captcha = ''.join(sample(list('abcdefghijklmnopqrstuvwxyz'), 4))
    print("生成的验证码为:", captcha)
    response = HttpResponse(image.generate(captcha), content_type='image/png')
    # response['Access-Control-Allow-Origin'] = '*'
    # response['Access-Control-Allow-Credentials'] = 'true'
    response.set_cookie('yzm', b64encode(captcha.encode()).decode(), max_age=60 * 5)
    return response

邮件验证码视图

文件 PersonalAccountWeb\views.py
邮件验证码就由后端校验,通过 session 保存,后续会用作异地登录验证(现在还没设计)。

def send_email_(to_address, header, html):
    smtp_server = settings.EMAIL_HOST
    msg = MIMEText(html, 'html', 'utf-8')
    msg['From'] = Header(settings.EMAIL_HOST_USER)
    msg['To'] = Header(to_address)
    msg['Subject'] = Header(header)
    server = smtplib.SMTP_SSL(smtp_server)
    server.connect(smtp_server, settings.EMAIL_PORT)
    server.login(settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD)  # python_gjj
    server.sendmail(settings.EMAIL_HOST_USER, to_address, msg.as_string())
    server.quit()


def send_email(request):
    if request.method == 'POST':
        to_address = loads(request.body)['email']
        if User.objects.filter(email=to_address):
            response = JsonResponse({'code': -1, 'msg': '邮箱已被注册!'})
        else:
            captcha = ''.join(sample(list('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 6))
            print("生成的邮件验证码为:", captcha)
            send_email_(to_address=to_address, header='邮箱验证码', html=f"""
            <h1>【个人记账分析系统】</h1>
            <p>您好,您正在注册我们的网站:<span style='color: red'><a href="http://{settings.CSRF_TRUSTED_ORIGINS[0]}">个人记账分析系统</a></span></p>
            <p>您本次注册的验证码是:<span style='color: blue'>{captcha}</span></p>
            <p>如果您<span style='color: red'>没有注册</span>,请<span style='color: red'>忽略并删除</span>本邮件!</p>
            <p>感谢您对本系统的信赖!</p>
            """)
            request.session['yzm'] = captcha
            request.session['email'] = to_address
            response = JsonResponse({'code': 0, 'msg': '邮箱验证码发送成功!请注意查收!'})
    else:
        response = JsonResponse({'code': 1, 'msg': '请求方法只能是POST方法!'})
    response.set_cookie('last', str(time()), max_age=60)
    return response

服务器时间视图

文件 PersonalAccountWeb\api.py
安装了 ninja 都没用过,只能在这里用了。

from time import time
from ninja import NinjaAPI

api = NinjaAPI()


@api.get('/server_timestamp')
def hello(request):
    return time()

路由部分

文件 PersonalAccountWeb\urls.py

from django.contrib import admin
from django.urls import path, include
from .api import api
from .views import verification_code, send_email

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', api.urls),
    path('yzm/', verification_code),
    path('email/', send_email),
    path('', include('payment.urls'))
]

文件 payment\urls.py

from django.urls import path
from .views import info, login_, logout_, register, check_online

urlpatterns = [
    path('info/', info),
    path('login/', login_),
    path('logout/',logout_),
    path('register/', register),
    path('check_online/', check_online)
]

前端部分

登录注册的UI参考了一个前端登录模板,略做修改就用在了我的项目上,前端登录模板 (点击即可跳转到下载页面)。

定义的路由

暂时这么多,后续可能会添加。

import { createApp } from 'vue'
import App from './App.vue'
import { createRouter, createWebHistory } from 'vue-router'
import C from './export_components.js'

const router = createRouter({
	history: createWebHistory(),
	routes: [
		{
			path: '/',
			name: '跳转至首页',
			redirect: '/Home',
		},
		{
			path: '/Home',
			name: '首页',
			component: C.Home,
			children: [
				{
					path: 'Login',
					name: '登录',
					component: C.Login
				},
				{
					path: 'Register',
					name: '注册',
					component: C.Register
				}
			]
		},
		{
			path: '/Backstage',
			name: '后台',
			component: C.Backstage,
			children: [
				{
					path: 'Settings',
					name: '设置',
					component: C.Settings
				},
				{
					path: 'DataEntry',
					name: '数据录入',
					component: C.DataEntry
				},
				{
					path: 'DataShow',
					name: '数据展示',
					component: C.DataShow,
					children: [
						{
							path: ':username',
							name: '用户展示',
							component: C.DataShow
						}
					]
				},
				{
					path: 'InStationMail',
					name: '站内邮件',
					component: C.InStationMail
				}
			]
		},
		{
			path: '/:pathMatch(.*)*',
			name: '404',
			// redirect: '/404',
			component: C.NotFound
		},
		// {
		// 	path: '/404',
		// 	name: '404',
		// 	component: NotFound
		// }
	]
})

createApp(App).use(router).mount('#app')

文件 App.vue

<script setup>
</script>

<template>
	<router-view></router-view>
</template>

<style scoped>
</style>

文件 Home.vue

主要保留了登录注册页的背景。

<template>
	<div class="main">
		<h1>个人记账分析系统</h1>
		<div class="login box">
			<router-view></router-view>
		</div>
		<div class="copywrite">
			<p>Copyright &copy; 2023</p>
		</div>
	</div>
</template>

<script setup>
	import { getCurrentInstance } from 'vue'
	document.title = '个人记账分析系统'
	const _this = getCurrentInstance().appContext.config.globalProperties // vue3获取当前this
	if (_this.$route.query.next) {
		_this.$router.push({ path: '/Home/Login', query: _this.$route.query})
	} else {
		_this.$router.push({ path: '/Home/Login', query: { next: '/Backstage' }})
	}
</script>

<style scoped>
	.main {
		font-family: 'Catamaran', sans-serif;
		font-size: 100%;
		background: linear-gradient(to left top, #051937, #004d7a, #008793, #00bf72, #a8eb12);
		background-size: cover;
		-webkit-background-size: cover;
		-moz-background-size: cover;
		-o-background-size: cover;
		-ms-background-size: cover;
		min-height: 100vh;
		text-align: center;
	}

	.login {
		display: -webkit-flex;
		display: -webkit-box;
		display: -moz-flex;
		display: -moz-box;
		display: -ms-flexbox;
		display: flex;
		justify-content: center;
		align-items: center;
		-webkit-box-pack: center;
		-moz-box-pack: center;
		-ms-flex-pack: center;
		-webkit-justify-content: center;
		justify-content: center;
	}

	h1 {
		font-size: 2.8em;
		font-weight: 300;
		text-transform: capitalize;
		color: #fff;
		text-shadow: 1px 1px 1px #000;
		letter-spacing: 2px;
		margin: 1.2em 1vw;
		margin-top: 0px;
		padding-top: 2.4em;
		text-align: center;
		font-family: 'Catamaran', sans-serif;
	}

	.copywrite {
		margin: 4em 0 2em;
	}

	.copywrite p {
		color: #fff;
		font-size: 14.5px;
		letter-spacing: 1.5px;
		line-height: 1.8;
		margin: 0 3vw;
	}

	.copywrite p a {
		color: #fff;
		transition: 0.5s all ease;
		-webkit-transition: 0.5s all ease;
		-moz-transition: 0.5s all ease;
		-o-transition: 0.5s all ease;
		-ms-transition: 0.5s all ease;
	}

	.copywrite p a:hover {
		color: #fff;
		text-decoration: underline;
	}

	@media(max-width:1024px) {
		h1 {
			font-size: 4.5vw;
		}
	}

	@media(max-width:800px) {
		h1 {
			font-size: 5vw;
		}
	}

	@media(max-width:480px) {
		h1 {
			font-size: 2.3em;
		}
	}

	@media(max-width:568px) {
		.login {
			flex-direction: column;
		}
	}

	@media(max-width:440px) {
		h1 {
			font-size: 2.1em;
		}
	}

	@media(max-width:320px) {
		h1 {
			font-size: 1.8em;
		}
	}
</style>

文件 Login.vue

<template>
	<form action="http://127.0.0.1:8000/login/" method="post" @submit.prevent="login">
		<div class="agile-field-txt">
			<input type="text" name="username" placeholder="用户名/邮箱" required="" />
		</div>
		<div class="agile-field-txt">
			<input :type="pwd == '隐' ? 'text' : 'password'" name="password" placeholder="密码" required="" />
			<a @click="pwd = pwd == '隐' ? '显' : '隐'">{{pwd}}</a>
		</div>
		<div class="yzm-field-txt">
			<input type="text" id="yzm" name="yzm" placeholder="验证码" required="" />
			<img :src="yzm_url" @click="yzm_url = 'http://127.0.0.1:8000/yzm/?time=' + new Date().getTime()"/>
		</div>
		<div class="bot">
			<input type="submit" value="LOGIN" @click="check_yzm">
		</div>
		<div class="agile-field-txt">
			<router-link to="/Home/Register?next=/Home/Login">还没有账户?点击注册</router-link>
		</div>
	</form>
</template>

<script setup>
	import { ref, getCurrentInstance } from 'vue'
	document.title = '个人记账分析系统'
	const pwd = ref('显')
	const yzm_url = ref('http://127.0.0.1:8000/yzm/')
	const _this = getCurrentInstance().appContext.config.globalProperties // vue3获取当前this
	const check_yzm = (event) => {
		const yzm = document.getElementById('yzm')
		var cookies = document.cookie.split("; ")
		for (var index in cookies) {
			if (cookies[index].startsWith('yzm=')) {
				if (btoa(yzm.value) == cookies[index].replace('yzm="', '').replace('"', '')) {
					return
				}
			}
		}
		yzm.value = ''
		yzm_url.value = 'http://127.0.0.1:8000/yzm/?time=' + new Date().getTime()
	}
	const login = (event) => {
		fetch('http://127.0.0.1:8000/login/', {
			method: "POST",
			credentials: "include",
			headers: {
				// 注意这里不要设置 Content-Type 请求头,否则会导致错误
			},
			Origin: window.location.protocol + "//" + window.location.host,
			// fetch 的 body 发送 data
			body: JSON.stringify({
				username: event.target.username.value,
				password: event.target.password.value
			})
		}).then(res => res.json()).then(json => {
			console.log(json.msg)
			if (!json.code) {
				_this.$router.push({ path: _this.$route.query.next || '/Backstage'})
			} else {
				alert(json.msg)
			}
		})
	}
</script>

<style scoped>
	a {
		top: 12px;
		z-index: 1;
		right: 10px;
		color: yellow;
		cursor: pointer;
		position: absolute;
		text-decoration: none;
	}

	.bot {
		margin-top: 1em;
		width: 100%;
	}

	form {
		max-width: 500px;
		margin: 0 5vw;
		padding: 3.5vw;
		border-width: 5px 0;
		box-sizing: border-box;
		display: flex;
		display: -webkit-flex;
		flex-wrap: wrap;
		background: rgba(252, 254, 255, 0.11);
	}

	.agile-field-txt {
		position: relative;
		flex-basis: 100%;
		-webkit-flex-basis: 100%;
		margin-bottom: 1.5em;
	}

	input[type="text"],
	input[type="password"] {
		width: 100%;
		color: #fff;
		outline: none;
		background: rgba(0, 0, 0, 0.32);
		font-size: 17px;
		letter-spacing: 0.5px;
		padding: 12px;
		box-sizing: border-box;
		border: none;
		-webkit-appearance: none;
		font-family: 'Catamaran', sans-serif;
	}

	::-moz-placeholder {
		/* Undefined */
		color: #eee;
	}

	::-webkit-input-placeholder {
		/* Firefox */
		color: #eee;
	}

	:-ms-input-placeholder {
		/* Chrome */
		color: #eee;
	}

	input[type=submit] {
		color: #ffffff;
		font-weight: 100;
		width: 100%;
		padding: 0.4em 0;
		font-size: 1em;
		font-weight: 400;
		letter-spacing: 2px;
		cursor: pointer;
		border: none;
		outline: none;
		background: #000;
		font-family: 'Catamaran', sans-serif;
		transition: 0.5s all ease;
		-webkit-transition: 0.5s all ease;
		-moz-transition: 0.5s all ease;
		-o-transition: 0.5s all ease;
		-ms-transition: 0.5s all ease;
	}

	input[type=submit]:hover {
		color: #fff;
		box-shadow: 0 20px 5px -10px rgba(0, 0, 0, 0.4);
		transform: translateY(5px);
	}
	
	.yzm-field-txt {
		float: left;
		width: 100%;
		height: 60px;
		position: relative;
	}
	
	.yzm-field-txt img {
		float: left;
	}
	
	.yzm-field-txt input {
		float: left;
		margin: 7px 0;
		width: calc(100% - 160px);
	}
</style>

文件 Register.vue

<template>
	<form action="http://127.0.0.1:8000/register/" method="post" @submit.prevent="register">
		<div class="agile-field-txt">
			<input type="text" name="username" placeholder="用户名" required="" />
		</div>
		<div class="agile-field-txt">
			<input :type="pwd == '隐' ? 'text' : 'password'" name="password" placeholder="密码" required="" />
			<a @click="pwd = pwd == '隐' ? '显' : '隐'">{{pwd}}</a>
		</div>
		<div class="agile-field-txt">
			<input type="email" name="email" placeholder="邮箱" required="" v-model="email" />
		</div>
		<div class="yzm-field-txt">
			<input type="text" name="yzm" placeholder="邮箱验证码" required="" />
			<input type="button" id="verification" value="邮箱验证码" @click="send_email" />
		</div>
		<div class="bot">
			<input type="submit" value="REGISTER">
		</div>
		<div class="agile-field-txt">
			<router-link to="/Home/Login?next=/Backstage">已有账户?点击登录</router-link>
		</div>
	</form>
</template>

<script setup>
	import { ref, getCurrentInstance } from 'vue'
	document.title = '个人记账分析系统'
	const _this = getCurrentInstance().appContext.config.globalProperties // vue3获取当前this
	const pwd = ref('显')
	const email = ref('')
	const timer = ref(null)
	const get_server_time = () => {
		var time = new Date().getTime() / 1000
		fetch('http://127.0.0.1:8000/api/server_timestamp', {
			method: "GET",
			credentials: "include",
			headers: {
				// 注意这里不要设置 Content-Type 请求头,否则会导致错误
			},
			Origin: window.location.protocol + "//" + window.location.host,
		}).then(res => {time = parseFloat(res)})
		return time
	}
	const calc_time = () => {
		var verification = document.getElementById('verification')
		var cookies = document.cookie.split("; ")
		for (var index in cookies) {
			if (cookies[index].startsWith('last=')) {
				var last = parseFloat(cookies[index].replace('last=', ''))
				var now = get_server_time()
				if (last + 59 > now) {
					verification.value = `重新发送(${parseInt(last + 59 - now)})`
					timer.value = setTimeout(calc_time, 800)
				} else {
					verification.value = '邮箱验证码'
					verification.disabled = false
					clearTimeout(timer.value)
				}
				return
			}
		}
	}
	const send_email = () => {
		var yzm = document.getElementById('verification')
		if (!email.value) {
			alert('请输入邮箱!')
			return
		}
		fetch('http://127.0.0.1:8000/email/', {
			method: "POST",
			credentials: "include",
			headers: {
				// 注意这里不要设置 Content-Type 请求头,否则会导致错误
			},
			Origin: window.location.protocol + "//" + window.location.host,
			// fetch 的 body 发送 data
			body: JSON.stringify({
				email: email.value
			})
		}).then(res => res.json()).then(json => {
			alert(json.msg)
			if (json.code >= 0) {
				verification.disabled = true
				timer.value = setTimeout(calc_time, 800)
			}
		})
	}
	const register = (event) => {
		if (!/^\w{6,18}$/.test(event.target.username.value)) {
			alert('用户名应该是长度为 6-18 的数字、大小写字母、下划线的组合!')
			return
		}
		if (!/^\w{6,18}$/.test(event.target.password.value)) {
			alert('密码应该是长度为 6-18 的数字、大小写字母、下划线的组合!')
			return
		}
		fetch('http://127.0.0.1:8000/register/', {
			method: "POST",
			credentials: "include",
			headers: {
				// 注意这里不要设置 Content-Type 请求头,否则会导致错误
			},
			Origin: window.location.protocol + "//" + window.location.host,
			// fetch 的 body 发送 data
			body: JSON.stringify({
				username: event.target.username.value,
				password: event.target.password.value,
				email: email.value,
				yzm: event.target.yzm.value
			})
		}).then(res => res.json()).then(json => {
			console.log(json.msg)
			if (!json.code) {
				_this.$router.push({ path: _this.$route.query.next || '/Home/Login'})
			} else {
				alert(json.msg)
			}
		})
	}
</script>

<style scoped>
	a {
		top: 12px;
		z-index: 1;
		right: 10px;
		color: yellow;
		cursor: pointer;
		position: absolute;
		text-decoration: none;
	}

	.bot {
		margin-top: 1em;
		width: 100%;
	}

	form {
		max-width: 500px;
		margin: 0 5vw;
		padding: 3.5vw;
		border-width: 5px 0;
		box-sizing: border-box;
		display: flex;
		display: -webkit-flex;
		flex-wrap: wrap;
		background: rgba(252, 254, 255, 0.11);
	}

	.agile-field-txt {
		position: relative;
		flex-basis: 100%;
		-webkit-flex-basis: 100%;
		margin-bottom: 1.5em;
	}

	input[type="text"],
	input[type="email"],
	input[type="password"] {
		width: 100%;
		color: #fff;
		outline: none;
		background: rgba(0, 0, 0, 0.32);
		font-size: 17px;
		letter-spacing: 0.5px;
		padding: 12px;
		box-sizing: border-box;
		border: none;
		-webkit-appearance: none;
		font-family: 'Catamaran', sans-serif;
	}

	::-moz-placeholder {
		/* Undefined */
		color: #eee;
	}

	::-webkit-input-placeholder {
		/* Firefox */
		color: #eee;
	}

	:-ms-input-placeholder {
		/* Chrome */
		color: #eee;
	}

	input[type=button] {
		color: yellow;
		width: 160px;
		height: 46px;
		padding: 0.4em 0;
		font-size: 1em;
		font-weight: 400;
		letter-spacing: 2px;
		cursor: pointer;
		border: 1px black solid;
		outline: none;
		background: rgba(0, 0, 0, 0);
	}

	input[type=submit] {
		color: #ffffff;
		font-weight: 100;
		width: 100%;
		padding: 0.4em 0;
		font-size: 1em;
		font-weight: 400;
		letter-spacing: 2px;
		cursor: pointer;
		border: none;
		outline: none;
		background: #000;
		font-family: 'Catamaran', sans-serif;
		transition: 0.5s all ease;
		-webkit-transition: 0.5s all ease;
		-moz-transition: 0.5s all ease;
		-o-transition: 0.5s all ease;
		-ms-transition: 0.5s all ease;
	}

	input[type=submit]:hover {
		color: #fff;
		box-shadow: 0 20px 5px -10px rgba(0, 0, 0, 0.4);
		transform: translateY(5px);
	}

	.yzm-field-txt {
		float: left;
		width: 100%;
		position: relative;
	}

	.yzm-field-txt input[type=text] {
		float: left;
		width: calc(100% - 160px);
	}
</style>

效果

在这里插入图片描述
在这里插入图片描述

总结

是不是看着登录注册界面简洁耐看呢~

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

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

相关文章

Word控件Spire.Doc 【图像形状】教程(8): 如何借助C#/VB.NET在 Word 中插入艺术字

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

基于51单片机的智能蓝牙路灯街灯控制系统proteus仿真原理图PCB

功能&#xff1a; 0.本系统采用STC89C52作为单片机 1.液晶实时显示时间/环境光强/工作模式 2.每隔5s向蓝牙串口发送一次信息 3.支持路灯故障检测 4.工作时间18~24时&#xff0c;两个路灯同时点亮&#xff0c;24时以后&#xff0c;B路灯关闭&#xff0c;若检测到由物体通过&…

【Kafka】Kafka的重复消费和消息丢失问题

文章目录前言一、重复消费1.1 重复消费出现的场景1.1.1 Consumer消费过程中&#xff0c;进程挂掉/异常退出1.1.2 消费者消费时间过长1.2 重复消费解决方案1.2.1 针对于消费端挂掉等原因造成的重复消费问题1.2.2 针对于Consumer消费时间过长带来的重复消费问题二、消息丢失2.1 生…

Multipass,多平台本地轻量级Linux体验!

Multipass 是由Ubuntu官方提供&#xff0c;在Linux&#xff0c;MacOS和Windows上快速生成 Ubuntu虚拟机 的工具。它提供了一个简单但功能强大的CLI&#xff0c;可让我们在本地快速进入Ubuntu系统环境并使用Linux命令&#xff0c;亦可以在本地计算机创建自己的迷你型云服务器。总…

zabbix监控网络连接状态

目录 一、环境准备 二、网络连接状态介绍 三、自定义监控key 四、给主机添加监控项 一、环境准备 1、搭建zabbix基础环境 zabbix基础环境部署参照&#xff1a;zabbix基础环境部署_桂安俊kylinOS的博客-CSDN博客 2、给web1安装nginx环境&#xff0c;并加载status模块 以…

SpringCloud学习笔记 - 链路监控 - SpringCloud Sleuth

1. Sleuth简介 在微服务框架中&#xff0c;一个由客户端发起的请求&#xff0c;在后端系统中会调用多个不同的的服务节点&#xff0c;来协同产生最后的响应结果&#xff0c;因此每一个前端请求都会形成一条复杂的分布式服务调用链路&#xff0c;链路中的任何一环出现高延时或错…

信号量Semaphore详解

前言 大家应该都用过synchronized 关键字加锁&#xff0c;用来保证某个时刻只允许一个线程运行。那么如果控制某个时刻允许指定数量的线程执行&#xff0c;有什么好的办法呢? 答案就是JUC提供的信号量Semaphore。 介绍和使用 Semaphore&#xff08;信号量&#xff09;可以用…

iwebsec靶场 SQL注入漏洞通关笔记10- 双重url编码绕过

系列文章目录 iwebsec靶场 SQL注入漏洞通关笔记1- 数字型注入_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记2- 字符型注入&#xff08;宽字节注入&#xff09;_mooyuan的博客-CSDN博客 iwebsec靶场 SQL注入漏洞通关笔记3- bool注入&#xff08;布尔型盲注&#…

VF01销售开票发票金额控制增强

实施隐式增强 全部代码如下&#xff1a; method IF_EX_BADI_SD_BILLING~INVOICE_DOCUMENT_CHECK. CALL FUNCTION ‘SIPT_DOC_CHECK_SD’ EXPORTING it_xvbrk fxvbrk it_xvbrp fxvbrp it_xkomv fxkomv it_xvbpa fxvbpa IMPORTING ev_bad_data fbad_data. “”“”“”“…

【LeetCode每日一题】——171.Excel 表列序号

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】七【题目提示】八【时间频度】九【代码实现】十【提交结果】一【题目类别】 字符串 二【题目难度】 简单 三【题目编号】 171.Excel 表列序号 四【题目描述】 给你一个字…

SecXOps 技术发展趋势

可以预见&#xff0c;安全智能分析技术的发展&#xff0c;将全面提升网络安全 关键应用场景下威胁检测的效果&#xff0c;推动安全分析从基础级、领先级&#xff0c;向卓越级演进。根据 Gartner 2021 年十大数据和分 析技术趋势&#xff0c;XOps 的目标是利用 DevOps 最佳实践实…

计算机网络性能指标——时延,时延带宽积,RTT和利用率

时延 时延&#xff1a;数据&#xff08;报文、分组、比特流&#xff09;从网络的一端传送到另一端所需要的时间。也叫延迟或迟延&#xff0c;单位是s。 时延包括&#xff1a;发送时延&#xff08;传输时延&#xff09;,传播时延&#xff0c;排队时延&#xff0c;处理时延。 高…

2022年最新安徽食品安全管理员模拟试题及答案

百分百题库提供食品安全管理员考试试题、食品安全管理员考试预测题、食品安全管理员考试真题、食品安全管理员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 1.引起副溶血弧菌食物中毒的主要食品是&#xff1a; A.罐头食品…

公司新来一个同事,把网关系统设计的炉火纯青,万能通用,稳的一批。。

本文准备围绕七个点来讲网关&#xff0c;分别是网关的基本概念、网关设计思路、网关设计重点、流量网关、业务网关、常见网关对比&#xff0c;对基础概念熟悉的朋友可以根据目录查看自己感兴趣的部分。 什么是网关 网关&#xff0c;很多地方将网关比如成门&#xff0c; 没什么…

操作系统学习(九)死锁

目录 学习建议&#xff1a; 基本内容&#xff1a; 一、死锁的形成&#xff1a; 二、死锁的必要条件&#xff1a; 三、资源分配图&#xff1a; 四、解决死锁问题的几个策略&#xff1a; 五、死锁的防止&#xff1a; 1.互斥条件&#xff1a; 2.占有并等待资源&#xff1a…

[NCTF2019]SQLi

进来就有个弹窗 甚至给了sql语句 sqlquery : select * from users where username and passwd 先扫一下目录&#xff0c;发现有个robots.txt 提示有个hint.txt $black_list "/limit|by|substr|mid|,|admin|benchmark|like|or|char|union|substring|select|greatest|%00…

特种品种权限开通和豁免

目前国内期货市场&#xff0c;许多商品期货品种需要特殊开户流程。主要有7个&#xff08;未包含期权以及金融期货&#xff09;&#xff1a;铁矿石、PTA、20号胶、低硫燃料油、棕榈油、原油、国际铜。 想要交易铁矿石&#xff0c;首先需要拥有一个期货账户&#xff0c;其次再向…

TCL 基于 StarRocks 构建统一的数据分析平台

作者&#xff1a;陈树煌&#xff0c;TCL 实业数据管理部副总监&#xff08;本文为作者在 StarRocks Summit Asia 2022 上的分享&#xff09; 作为伴随改革开放浪潮成长起来的中国领先电子企业&#xff0c;TCL 拥有 13 万员工&#xff0c;业务遍及 160 多个国家和地区&#xff…

[附源码]计算机毕业设计springboot公共台账管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【重温C++ Primer】第一章、初识C++

目录前言一、编写一个简单的c程序二、编译、运行程序三、初识输入输出四、注释类型五、控制流5.1、循环语句&#xff1a;while for5.2、读取数量不定的输入数据5.2、if 语句六、类Reference前言 上次学C还是在大一的时候&#xff0c;一直都想好好的温习一下C。刚好最后被隔离…