【快速上手系列】用于登录的验证码制作(ValidateCode)和Javaweb自带的老式验证码快速上手

news2025/8/12 0:14:10

【快速上手系列】用于登录的验证码制作(ValidateCode)和Javaweb自带的老式验证码快速上手

验证码

简介

验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。一种常用的CAPTCHA测试是让用户输入一个扭曲变形的图片上所显示的文字或数字,扭曲变形是为了避免被光学字符识别(OCR, Optical Character Recognition)之类的电脑程序自动辨识出图片上的文字而失去效果。为了无法看到图像的身心障碍者,替代的方法是改用语音读出文数字,为了防止语音辨识分析声音,声音的内容会有杂音。

作用

  • 防止批量注册、刷票、论坛灌水、刷页。
  • 有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登录尝试。
  • 验证码通常使用一些线条和一些不规则的字符组成,主要作用是为了防止一些黑客把密码数据化盗取。

常见的验证码

  1. 传统输入式验证码
    主要是通过用户输入图片中的字母、数字、汉字等进行验证。
    代表:大多数网站采用此种验证形式。
    特点:简单易操作,人机交互性较好。但安全系数低,容易被破解。
  2. 输入式的图形验证码
    有精美图案,识别文本也清晰可认,专注于广告。
    代表:Solve Media,宇初验证码
    特点:与其说是验证码,倒不如说是广告位。
  3. 纯行为验证码
    照要求将备选碎片直线滑动到正确的位置
    代表:极验验证码
    特点:操作简单,体验好。单一维度,容易被逆向模拟,与移动端页面切换不兼容。
  4. 图标选择与行为辅助
    给出一组图片,按要求点击其中一张或者多张。借用万物识别的难度阻挡机器。
    代表:点触验证码、Google新型验证码、12306验证码
    特点:安全性强。对于图片、图库、技术要求高。
  5. 点击式的图文验证与行为辅助
    通过文字提醒用户点击图中相同字的位置进行验证。
    代表:淘宝新型验证码、点触验证码
    特点:操作简单,体验良好,单一图片区域较大,破解难度大。
  6. 智能验证码
    通过行为特征、设备指纹、数据风控等技术,正常用户免验证,异常用户强制验证
    代表:点触智能验证码
    特点:简单便捷,区分人与机器、人与人、设备与设备。

具体使用

Servlet版本

步骤

1、导入jar包到你的web项目

ValidateCode.jar

maven依赖:

<!-- ValidateCode验证码 -->
<dependency>
    <groupId>cn.dsna</groupId>
    <artifactId>ValidateCode</artifactId>
    <version>1.0.0</version>
</dependency>

2、编码过滤器中多一个配置(防止乱码)

//设置图像编码集
response.setContentType("image/jpeg;charset=utf-8");

3、配置验证码Servlet文件ValidateCodeServlet.java

@WebServlet("/ValidateCodeServlet")
public class ValidateCodeServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
				
		//四个参数:验证码宽度、验证码高度、验证码有几位,验证码有几个干扰项
		ValidateCode validateCode = new ValidateCode(110,26,4,10);
		String code = validateCode.getCode();
		System.out.println(code);
        //在这一步存入code值(就是图片中验证码的字母和数字),用于一会在登录Servlet中接收进行判断用户输入的验证码是否和图片中的验证码一致
		request.getSession().setAttribute("code", code);
		//图片响应给客户端
		validateCode.write(response.getOutputStream());

	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

如果直接访问此Servlet页面就可以看到即将显示的验证码图片:

请添加图片描述

4、配置前端jsp页面(html都行,看着改)

<!-- 配置cookie(html不用这) -->
<%
String ucode = "";
String upwd = "";
//用request获取cookie
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length != 0) {
    for (Cookie cookie : cookies) {
        if (cookie.getName().equals("usercode")) {
            //获得cookie值
            ucode = cookie.getValue();
            //如果其值存在中文,就将其解码
            ucode = URLDecoder.decode(ucode,"utf-8");
        }
        if (cookie.getName().equals("upwd")) {
            //获得cookie值
            upwd = cookie.getValue();
        }

    }
}
%>


<!-- html代码(value不用要) -->
<!-- 用value设置cookie默认值 -->
账号:<input type="text" id="usercode" name="ucode" value="<%=ucode%>"/><br/>	
密码:<input type="text" id="userpwd" name="upwd" value="<%=upwd%>"/><br/>

<!-- 这里是验证码 -->
验证码:<input name="validatecode" id="validatecode" placeholder="验证码" type="text">
<a href="javascript:fn1()" style="text-decoration:none;">看不清,换一张<br/><img id="imageCode" src="/web08/ValidateCodeServlet(访问验证码Servlet的路径)" /></a>
<br/><br/>
<input type="button" id="loginbtn" value="提交"/>

js代码(我这都写一起了,单独写的粘所需即可):

<script type="text/javascript" src="js/jquery-3.6.0.js" charset="UTF-8"></script>
<script type="text/javascript">
	
//改变验证码
function fn1(){
	//随便一个参数或者随机数,使图片转换	(可能因为验证码缓存所以不设置的话只能换一次)
	var d = new Date();	//(因为日期时间比较唯一)
	document.getElementById("imageCode").src = "/web08/ValidateCodeServlet?t="+d.getTime();
	
}

	//登录的点击事件:
	$(function(){
				
		$("#loginbtn").click(function(){
			//通过id得到值
			 var usercode = $("#usercode").val();
			 var userpwd = $("#userpwd").val();
			 var validatecode = $("#validatecode").val();
			 $.get("LoginServlet",
					 {usercode:usercode,userpwd:userpwd,validatecode:validatecode},
					 function(res){
						 alert(res.msg);  //判断登录对错状态
						 if(res.code==1){
							 location = "/web08/web/ProviderAllServlet(跳到成功登录后的页面)"
						 }else {
							 location = "/web08/login.jsp(原地刷新)"
						 }
					 },
					 "json");
		});
	});


</script>

写好后的前端效果:

请添加图片描述

然后配置自己项目中的登录Servlet(我这里是LoginServlet.ava):

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public LoginServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String json=null;
		//设置网页字符编码集
        response.setContentType("text/html;charset=utf-8");
        
        //设置接收参数
        String ucode = request.getParameter("usercode");
        String upwd = request.getParameter("userpwd");
        String validatecode = request.getParameter("validatecode");
        //登录方法
      	UserService us = new UserServiceImpl();
      	User user = new User();
      	user = us.login(ucode, upwd);
      	//1、看验证码是否为null或是空字符串,如果不是进行下一步判断
      	if(validatecode == null || validatecode.equals("")) {
			json = "{\"code\":2,\"msg\":\"验证码不能为空!!\"}";
		}else {
            //2、拿取当时从验证码Servlet中得到的code(也就是验证码信息),然后与用户输入的验证码进行比较,若比较成功则进行下一步用户登录验证的判断,否则返回验证码错误的信息
			String code = (String)request.getSession().getAttribute("code");
            //忽略大小写进行比较
			if(validatecode.equalsIgnoreCase(code)) {
                //3、比较相等后,开始写登录的业务判断
				if(user != null) {
					String uname = user.getUserName();
					request.setAttribute("ucode",ucode);
					request.setAttribute("uname",uname);
					//设置Cookie
					//如果Cookie中值存在中文,就将其编码设置成utf-8(也可能因为设置了反而乱码,看具体情况)
					String usercode = URLEncoder.encode(ucode, "utf-8");
					Cookie cookie = new Cookie("usercode",usercode);
					//设置路径为根目录(方便使用)
					cookie.setPath("/");
					//设置cookie生命周期
					cookie.setMaxAge(20);	//s
					//添加cookie(response)
					response.addCookie(cookie);
					
					Cookie cookie1 = new Cookie("upwd",upwd);
					//设置路径为根目录(方便使用)
					cookie1.setPath("/");
					//设置cookie生命周期
					cookie1.setMaxAge(20);	//s
					//添加cookie(response)
					response.addCookie(cookie1);
					
					//创建session
					HttpSession session = request.getSession();
					//存入用户session
					session.setAttribute("uname", uname);
					//设置session过期时间
					session.setMaxInactiveInterval(60 * 60);
					
					json = "{\"code\":1,\"msg\":\"登录成功\"}";
					//response.sendRedirect("web/ProviderAllServlet");
				} else {
					json = "{\"code\":2,\"msg\":\"登录失败\"}";
					//response.sendRedirect("/login.jsp");
				}
			}else {
				json = "{\"code\":2,\"msg\":\"验证码错误!!\"}";
			}
		}
		//回应控制台输出:
		PrintWriter out = response.getWriter();
		out.print(json);
		System.out.println(json);
	}
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

这样就整好了

另一种老式验证码

用的是java.awt下自带的验证码,很麻烦,需要自己一步一步算是画个验证码出来,不过一些特性都可以自定义设置:

package com.r.servlet;

import java.io.IOException;
import java.util.Random;

import java.awt.image.BufferedImage;
import java.awt.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 验证码
 * @author
 *
 */

@WebServlet("/ValidateCodeServlet2")
public class ValidateCodeServlet2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	private void codeChange(HttpServletResponse response) throws IOException{
		int width=120;
		int height=27;
		/**
		 * 1.在内存中创建一个图像对象
		 */
		//构造一个类型为预定义图像类型之一的 BufferedImage。
		//表示一个具有 8 位 RGB 颜色分量的图像,对应于 Windows 或 Solaris 风格的 BGR 颜色模型,具有打包为整数像素的 Blue、Green 和 Red 三种颜色。			
		BufferedImage img=new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
																							
		//创建一个画笔
		Graphics g=img.getGraphics(); 
		
		//给背景图片添加一个颜色
		g.setColor(Color.ORANGE);
		g.fillRect(1, 1, width-2, width-2);//建议使用IE浏览器访问,Google浏览器和获取均显示为居中的图片,ie显示左上角
		
		//给边框一个色
		g.setColor(Color.GREEN);
		g.drawRect(0, 0, width-1, height-1);
		
		//设置文本样式
		Random rr = new Random();
		g.setColor(Color.BLACK);
		g.setFont(new Font("宋体",Font.BOLD|Font.ITALIC,15));//Font对象 ----根据指定名称、样式和磅值大小,创建一个新 Font。
		g.setColor(new Color(rr.nextInt(255),rr.nextInt(255),rr.nextInt(255)));  //设置颜色,它的红,绿,蓝都在0~255之间随机
		
		//给图片添加文本
		Random rand=new Random();
		int position=20;
		for(int i=0;i<4;i++){
			g.drawString(rand.nextInt(10)+"", position, 20);//给图片填充文本
			position+=20;
		}
		
		//给图片加噪点
		for(int i=0;i<20;i++){
            Random r = new Random();
            int x = r.nextInt(width);
            int y = r.nextInt(height);
            g.drawOval(x,y,5,5);
        }


		//将图片以对象流的方式输出到客户端
		ImageIO.write(img, "jpg", response.getOutputStream());
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		codeChange(response);

	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

这是效果:

请添加图片描述

也可以每个字符都变颜色

package com.r.servlet;

import java.io.IOException;
import java.util.Random;

import java.awt.image.BufferedImage;
import java.awt.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ValidateCodeServlet3
 */
@WebServlet("/ValidateCodeServlet3")
public class ValidateCodeServlet3 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ValidateCodeServlet3() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
      }
      //图片的高度,宽度,文本的个数
      private static final int IMG_HEIGHT = 30;
      private static final int IMG_WIDTH = 100;
      private static final int IMG_NUM = 4;
      @Override
      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.设置响应头,图片的缓存
        resp.setHeader("Pragma", "no-cache");
        resp.setHeader("Cache-Control", "no-cache");
        //设置响应的内容类型,MIME TYPE
        resp.setContentType("image/jpeg");
        //创建绘制图片的缓存流,BufferedImage.TYPE_INT_RGB图片为三原色图片
        BufferedImage bi = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_RGB);
        //获取画笔对象
        Graphics g = bi.getGraphics();
        //设置画笔的颜色
        g.setColor(new Color(100,230,200));
        //绘制图片的背景色
        g.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT);
        //验证码中使用字符
        char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray();
        //创建随机数
        Random random = new Random();
        //创建StringBuffer存储随机字符
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < IMG_NUM; i++) {
          //生成随机数
          int index = random.nextInt(chars.length);
          //取出随机字符
          char randomChar = chars[index];
          //设置画笔颜色
          g.setColor(new Color(random.nextInt(150),random.nextInt(200),random.nextInt(255)));
          //设置文本字体
          g.setFont(new Font("Arial",Font.PLAIN,18));
	       //给图片加噪点
	  	   for(int j=0;j<7;j++){
	          Random r = new Random();
	          int x = r.nextInt(IMG_WIDTH);
	          int y = r.nextInt(IMG_HEIGHT);
	          g.drawOval(x,y,5,5);
	       }
          //将字符绘制到图片上
          g.drawString(String.valueOf(randomChar), 15+(i*20), 20);
          //将随机字符放入StringBuffer中
          buffer.append(randomChar);
        }
        //将存储随机字符的String对象放入Session中
        req.getSession().setAttribute("validateCode", buffer.toString());
        //通过ImageIo流,将图片输出到页面中
        ImageIO.write(bi, "jpg", resp.getOutputStream());
      }
}

效果:

请添加图片描述

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

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

相关文章

易基因|疾病研究:DNA甲基化和转录组学特征在高浆卵巢癌复发和耐药过程中高度保守

易基因&#xff5c;疾病研究&#xff1a;DNA甲基化和转录组学特征在高浆卵巢癌复发和耐药过程中高度保守 大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 2022年07月27日&#xff0c;《J Exp Clin Cancer Res》杂志发表了题为“DNA me…

Linux|centos7下部署安装alertmanager并实现邮箱和微信告警(三)

前言&#xff1a; 前文Linux|centos7下部署安装alertmanager并实现邮箱和微信告警&#xff08;二&#xff09;_晚风_END的博客-CSDN博客 实现了告警系统模块的部署和测试&#xff0c;主要的告警范围是服务器节点的操作系统内存&#xff0c;磁盘空间的使用率这些方面&#xff0…

甘露糖-聚乙二醇-N-羟基琥珀酰亚胺mannose-PEG-NHS

甘露糖-聚乙二醇-N-羟基琥珀酰亚胺mannose-PEG-NHS 琥珀酰亚胺又称为丁酰亚胺或丁二酰亚胺&#xff0c;是一种无色针状结晶或具有淡褐色光泽的薄片固体&#xff0c;味甜。易溶于水、醇或氢氧化钠溶液&#xff0c;不溶于醚、氯仿等&#xff0c;可以提供PEG接枝修饰甘露糖&#…

精彩回顾!2022VisionChina深圳展圆满落幕

11月16日&#xff0c;维科杯•OFweek 2022中国工业自动化及数字化行业年度评选颁奖典礼在深圳大中华喜来登酒店举行&#xff0c;经过OFweek网络投票、专家组评审及组委会综合评审三轮激烈紧张的评选&#xff0c;昂视凭借“PiqsVT智能视觉系统”在近300个参评项目中脱颖而出&…

Linux三个踩坑过程记录

今早花了一早上的时间解决了三个Linux的问题&#xff0c;分别是读写权限、克隆虚拟机开启问题和Xshell连接VM虚拟机问题。平时用虚拟机比较少&#xff0c;现在刚一开始用&#xff0c;就给我来了三个问题让我解决&#xff0c;真是含泪解决问题&#xff0c;但现在解决了&#xff…

预定2.0 Crack ZoomCharts JavaScript 最值得探索

世界上最可探索的 JavaScript 图表 将内容深入分析和支持多点触控的大数据可视化轻松集成到您的 Web 项目中--ZoomCharts JavaScript 快速、简单且令人印象深刻的 JavaScript 图表 以极快的速度将 javascript 图表与令人惊叹的向下钻取功能集成&#xff0c;一定会给您的团队、…

Word控件Spire.Doc 【文本】教程(22) ;在 Word 中应用强调标记(C#/VB.NET)

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

Live800:在线客服系统如何帮助企业创造持续的服务价值?

德鲁克管理箴言&#xff1a;企业的唯一目的就是“创造顾客”。 如何创造顾客&#xff1f;只能依靠产品和服务。产品和服务是连接企业与客户的天然纽带和必然桥梁。 企业依靠持续不断生产满足客户需求、符合客户价值主张的优质产品和服务来创造客户、留住客户并建立客户忠诚度…

视频怎么添加水印?快来收好这些方法

如今短视频行业发展得如火如荼&#xff0c;很多小伙伴都投入了短视频制作中。我最初发布视频只是因为热爱记录日常&#xff0c;顺便还能增进一下自己的视频剪辑水平。刚开始没想那么多&#xff0c;视频制作好就直接传到平台上去了&#xff0c;后来才发现自己的视频被别人搬运&a…

高通量筛选化合物库抑制缺氧诱导因子抑制剂

研究证明了土著细菌具有铁依赖性机制&#xff0c;可以抑制宿主铁的运输和储存。通过微生物代谢物的高通量筛选&#xff0c;研究人员发现&#xff0c;肠道菌群产生的代谢物能抑制肠道铁吸收主要转录因子低氧诱导因子 2α (HIF-2α)&#xff0c;并增加铁存储蛋白铁蛋白 (Ferritin…

SpringBoot SpringBoot 开发实用篇 4 数据层解决方案 4.3 H2数据库

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇4 数据层解决方案4.3 H2数据库4.3.1 问题引入4.3.2 内置数据库4.3.3 …

微信小程序使用npm教程

首先打开工具-详情-勾选使用npm模块 使用npm的步骤&#xff1a; 1. 安装 npm 包 在小程序 package.json 所在的目录中执行命令安装 npm 包&#xff1a; npm install此处要求参与构建 npm 的 package.json 需要在 project.config.json 定义的 miniprogramRoot 之内。 tips&am…

【大数据存储技术】思考题及参考答案

文章目录第1章 绪论1. NoSQL和关系型数据库在设计目标上有何主要区别&#xff1f;2. 简要总结一下NoSQL数据库的技术特点。第2章 NoSQL数据库的基本原理1. 描述分布式数据管理的特点。2. 什么是CAP原理&#xff1f;CAP原理是否适用于单机环境&#xff1f;3. 简述BASE理论的具体…

【附源码】计算机毕业设计JAVA校园疫情防控管理软件

【附源码】计算机毕业设计JAVA校园疫情防控管理软件 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JAVA…

(SVN+SSH)搭建SVN并使用SSH进行免密拉取推送代码

【SVNSSH】搭建SVN并使用SSH进行免密拉取推送代码一、安装svn、openssh-server服务二、开启svn服务&#xff0c;创建测试仓库&#xff0c;并能通过账号密码拉取定义svn仓库文件位置创建仓库:acc_repo配置拉取仓库的账号密码通过账号密码拉取代码三、创建测试仓库&#xff0c;通…

云安全系列3:如何构建云安全策略

云计算拯救了很多企业&#xff0c;因为它可以迅速调整以支持更大规模的工作以及更多的在线用户。随着2023年的到来&#xff0c;宏观经济逆风聚集&#xff0c;它将更加具有吸引力&#xff0c;这归功于它更高的业务敏捷性和更优的成本效率比。Gartner 预测&#xff0c;到 2023 年…

聚观早报|腾讯员工平均月薪超8万;马斯克考虑卸任特斯拉CEO

今日要闻&#xff1a;腾讯员工平均月薪超8万&#xff1b;马斯克考虑卸任特斯拉CEO&#xff1b;iPhone双十一销量近350万部&#xff1b;暴雪将在大陆暂停多数服务&#xff1b;高德地图上线北斗卫星定位查询系统腾讯员工平均月薪超8万 据报道&#xff0c;腾讯控股11月16日发布202…

4-8岁儿童EEG微状态研究:年龄和性别的影响

大规模神经网络的超快时空动态可以通过静息状态脑电图&#xff08;EEG&#xff09;微观状态来检验&#xff0c;这代表了随时间动态演化的同步神经活动的短暂时期。在成人中&#xff0c;四种典型的微观状态已被证明可以解释静息状态脑电图的大部分地形差异。它们的时间结构依赖于…

【北亚数据恢复】硬盘出现坏道的数据恢复方案

经常使用电脑和移动硬盘的用户&#xff0c;如果察觉到电脑运行速度变得很慢&#xff0c;即使做了磁盘整理和系统重装操作后速度还是没有恢复到正常状态&#xff0c;这个时候就要小心是硬盘盘片出现坏道了。 如果这个时候用硬盘检测软件扫描硬盘就会发现扫描界面上出现很多绿块&…

SEO的了解

什么是SEO SEO&#xff0c;也就是搜索引擎优化的逻辑&#xff0c;其实是非常简单的。这就像是在大学里的学生会主席&#xff0c;你要让投票者给你更多的选票。那么&#xff0c;你需要先「自我优化」&#xff0c;无论是外表还是能力&#xff1b;此外&#xff0c;你还需获得更多…