精华内容
下载资源
问答
  • 手机验证码

    2014-02-23 17:57:03
    手机验证码
  • 今天子恒老师来跟你分享怎么实现发送手机验证码给用户, 注意我们使用的是php开发,实现发送验证码功能。 一、 生成手机验证码 手机短信验证码的功能, 主要是判断用户的真实性, 同时又要让用户在...

    通过前面的学习,

    你已经掌握怎么在腾讯短信平台上设置项目

    添加短信签名

    设置短信模板

    手机验证码注册页面写好。

    今天子恒老师来跟你分享怎么实现发送手机验证码给用户,

    注意我们使用的是php开发,实现发送验证码功能。

    一、 生成手机验证码

    手机短信验证码的功能,

    主要是判断用户的真实性,

    同时又要让用户在后面输入验证码时非常方便。

    所以生成的验证码最好是具有下面的特征:

    1) 手机验证码最好是全部数字

    有的公司把短信验证码搞得很复杂,

    弄成数字加字母的形式,

    这种验证码用户收到后很难记住,

    输入也麻烦,

    特别是用手机输入的时候,

    切换来切换去,

    很浪费时间。

    2) 手机验证码位数最好是4位或6位

    验证码超过6位,

    用户也是很难记住的。

    二、 发送验证码给用户

    这个我们使用腾讯手机验证码平台的接口,

    先通过短信模板生成验证码内容,

    再用php把相关数据提交给腾讯接口就行,

    具体可以看文章末尾的视频教程

    发送手机验证码

    发送手机验证码

    三、 保存手机验证码

    手机验证码发送完后,

    并没有马上结束,

    因为我们后面还要验证用户发送过来的验证码。

    所以发送完后,

    我们需要把刚才发送的验证码保存到我们的服务器。

    验证码是保存到session 还是cookie?

    这个也是经常有学员咨询的问题,

    其实验证码属于机密信息,

    只能保存到服务器,

    因为你保存在cookie时,

    别人是可以修改cookie中的验证码,

    到时你接收过来做验证码就不安全了。

    在服务器端,你可以保存到session,也可以保存到缓存,

    比如把手机验证码保存到memcache, redis等,

    也可以保存到数据库,

    你可以根据自己的情况实现。

    发送手机验证码具体实现和相关代码,

    点击这里观看视频教程

    《php开发手机验证码短信接口》

    http://edu.csdn.net/course/detail/3426/58723

    展开全文
  • 手机验证码接收

    2016-08-15 17:43:38
    获取手机验证码
  • 验证码,手机验证码,不区分大小写验证码
  • 手机验证码代码

    2017-05-13 01:56:57
    手机验证码代码,具体演示可以看我写的博客文章,地址 http://blog.csdn.net/lvjinhan/article/details/71774632
  • java实现手机验证码

    2018-10-01 22:30:09
    spring+maven实现手机验证码
  • android手机验证码

    2014-10-31 10:18:09
    注册时由服务器发送验证码手机手机输入正确的验证码填写后方可注册成功
  • 手机验证码登录

    2019-07-12 14:25:53
    记一次手机验证码登录实现流程

    手机验证码登录

    符号说明:

    []:表示可选或某些条件下流程。

    需求说明:

    用户可在登录页面使用手机验证码登录,若该手机号未绑定则输入验证码后还需输入用户账号密码进行绑定,绑定后则成功使用验证码登录。

    用户可在控制台进行新增、修改、删除绑定手机号的操作。每个用户最多绑定两个手机号。

    1.流程分析

    a.输入手机号点击发送验证码 —> b.输入验证码点击确认按钮 —> [c.未绑定的手机号需要绑定到用户]

    每一步都需要向后台发送一个请求,三个请求组成一个流程。通过Redis保存请求间的联系。关于SpringMVC集成Redis可参考文章:Redis单点与集群连接

    ps:为什么要使用Redis? Redis存取方便,性能更好,并可以方便的控制对象的存活时间。

    直接使用短信验证码登录,新绑定手机号,与修改手机号主要流程相同但部分细节方面需要进行不同的处理,使用策略模式实现不同细节的处理。

    2.代码逻辑

    2.1 Controller层

    2.1.1 登录页面发送验证码接口。对应流程a。参数为手机号,[是否为修改绑定的标识],[旧手机号码(若为修改绑定则必传)]。发送验证码到手机,接口返回一个随机数和一个标识是否首次绑定

    前端根据此标识调用不同接口,若已绑定过则调用2.1.2接口获取登录成功后的字段(如token信息);若未绑定则调用2.1.3接口进行绑定操纵。

    后台可根据是否为修改绑定,是否为首次绑定调用不同的策略。具体策略下文细讲。

    ps:发送验证码接口可生成一个随机数返回给前端,随机数作为key存放在Redis中,value中存放如手机号等校验验证码时需要的信息。

    2.1.2 验证验证码接口。参数为验证码,接口2.1.1生成的随机数,其他登录所需校验参数。接口验证验证码是否正确。

    若验证码正确则返回登录成功后的字段(如token)。

    2.1.3 验证验证码接口。参数为验证码,接口2.1.1生成的随机数。返回一个随机数。

    接口验证验证码是否正确,若验证码正确则生成随机数作为key存放在Redis中,value为手机号等信息。

    2.1.4 绑定用户接口。参数为 用户名,密码,接口2.1.3生成的随机数,[是否使用改手机号登录标识,不传默认为false],[其他登录所需校验参数]。

    校验通过后,将手机号存入数据库与用户关联。若登录标识为true,则返回登录成功后的字段(如token)。

    2.2 Service层

    Service层类图如下

    service层策略类图

    抽象类提供了protected访问权限的公共方法(generateVC;verifyVC;userLogin());子类可按需调用。子类实现抽象方法实现每种情景下的访问细节。Controller层根据不同情况调用不同策略。

    将我实现的手机验证码登录流程做个总结,希望有大佬可以指出其中的不足。

    展开全文
  • 近来由于项目需要,需要用到手机短信验证码的功能,其中最主要的是用到了第三方提供的短信平台接口WebService客户端接口,下面我把我在项目中用到的记录一下,以便给大家提供个思路,由于本人的文采有限,还请大家...

    近来由于项目需要,需要用到手机短信验证码的功能,其中最主要的是用到了第三方提供的短信平台接口WebService客户端接口,下面我把我在项目中用到的记录一下,以便给大家提供个思路,由于本人的文采有限,还请大家见谅!

    一:首先上几张案例截图,以便大家可以了解一下短信验证码的流程,这里我在做的过程中也参考了很多网站的短信验证码,比如:58同城,汽车之家等。

    1.点击获取验证码之前的样式:

    2.输入正确的手机号后点击获取验证码之后的样式:

    3.如果手机号已经被注册的样式:

    4.如果一个手机号一天发送超过3次就提示不能发送:

    二:前台的注册页面的代码:reg.jsp

     

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@taglib prefix="s" uri="/struts-tags"%>
    <%@page import="cn.gov.csrc.base.action.FindAllData"%>
    <%
    	String path = request.getContextPath();
    	String basePath = request.getScheme() + "://"
    			+ request.getServerName() + ":" + request.getServerPort()
    			+ path + "/";
    %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <base href="<%=basePath%>">
    <title>中国证券会证券期货违法违规举报中心-注册</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <link rel="shortcut icon" type="image/x-icon" href="<%=request.getContextPath()%>/images/favicon.ico" />
    <link rel="stylesheet" type="text/css"
    	href="<%=request.getContextPath()%>/css/main.css">
    <link
    	href="<%=request.getContextPath()%>/formValidator1/style/validator.css"
    	rel="stylesheet" type="text/css" />
    <style type="text/css">
    button {
    	background: #F0F0F0 repeat-x;
    	padding-top: 3px; 
    	border-top : 1px solid #708090;
    	border-right: 1px solid #708090;
    	border-bottom: 1px solid #708090;
    	border-left: 1px solid #708090;
    	width: auto;
    	line-height: 12pt; 
    	font-size : 10pt;
    	cursor: hand;
    	font-size: 10pt;
    	border-top: 1px solid #708090;
    }
    </style>
    <script src="<%=request.getContextPath()%>/js/jquery-1.7.2.min.js"
    	type="text/javascript"></script>
    <script src="<%=request.getContextPath()%>/formValidator1/formValidator-4.0.1.js"
    	type="text/javascript"></script>
    <script src="<%=request.getContextPath()%>/formValidator1/formValidatorRegex.js"
    	type="text/javascript"></script>
    <script src="<%=request.getContextPath()%>/js/register.js"
    	type="text/javascript"></script>
    <script src="<%=request.getContextPath()%>/js/sms.js"
    	type="text/javascript"></script>
    <script type="text/javascript">
    	function changeCheckNum() {
    		var checkNumImage_ = document.getElementById("checkNumImage");
    		checkNumImage_.src = "${pageContext.request.contextPath}/image.jsp?timeStamp="+ new Date().getTime();
    	}
    </script>
    <script type="text/javascript">
    	var msg = "${message}";
    	if (msg != "") {
    		alert(msg);
    	}
    </script>
    </head>
    <body>
    	<%@include file="/statics/top.jspf"%>
    	<div class="center_division">
    		<div class="center_body">
    			<div class="center_menu">
    				<font color="#000000">当前位置:</font>
    				<a href="<%=request.getContextPath()%>/statics/reg.jsp"><font color="#000000">用户注册</font></a>
    			</div>
    		</div>
    		<div class="center_body_menu">
    			<s:form action="RegisterAction_register" id="form1" name="form1" method="post" namespace="/">
    				<table id="tb">
    					<tr>
    						<td colspan="3" align="center" bgcolor="#DDDFE1">举报人基本信息</td>
    					</tr>
    					<tr>
    						<td align="center" width="30%">    <img src="images/new_reg_xing.gif"/>用户名:</td>
    						<td align="center" width="40%">
    							<s:textfield name="username" id="username" cssStyle="width:160px;height:24px;" onblur="checkusername()"/>
    						</td>
    						<td align="left" width="30%">
    							<span id="usernameTip">
    								<s:fielderror cssStyle="color:red;padding-left:10px;">
    									<s:param>username</s:param>
    								</s:fielderror>
    							</span>
    						</td>
    					</tr>
    					<tr>
    						<td align="center" width="30%"><img src="images/new_reg_xing.gif"/>登录密码:</td>
    						<td align="center" width="40%">
    							<s:password name="password" id="password" cssStyle="width:160px;height:24px;" onblur="checkpassword()"/>
    						</td>
    						<td align="left" width="30%">
    							<span id="passwordTip">
    								<s:fielderror cssStyle="color:red;padding-left:10px;">
    									<s:param>password</s:param>
    								</s:fielderror>
    							</span>
    						</td>
    					</tr>
    					<tr>
    						<td align="center" width="30%"><img src="images/new_reg_xing.gif"/>确认密码:</td>
    						<td align="center" width="40%">
    							<s:password name="passwordRepeat" id="passwordRepeat" cssStyle="width:160px;height:24px;" onblur="checkpasswrodb()"/>
    						</td>
    						<td align="left" width="30%">
    							<span id="passwordRepeatTip">
    								<s:fielderror cssStyle="color:red;padding-left:10px;">
    									<s:param>passwordRepeat</s:param>
    								</s:fielderror>
    							</span>
    						</td>
    					</tr>
    					<tr>
    						<td align="center" width="30%"><img src="images/new_reg_xing.gif"/>姓        名:</td>
    						<td align="center" width="40%">
    							<s:textfield name="nickname" id="nickname" cssStyle="width:160px;height:24px;" onblur="checknickname()"/>
    						</td>
    						<td align="left" width="30%">
    							<span id="nicknameTip">
    								<s:fielderror cssStyle="color:red;padding-left:10px;">
    									<s:param>nickname</s:param>
    								</s:fielderror>
    							</span>
    						</td>
    					</tr>
    					<tr>
    						<td align="center" width="30%">性        别:</td>
    						<td align="center" width="40%">
    							<s:radio list="#application.dataMap.get('10001')" name="jbSex" cssStyle="height:24px;"/>
    						</td>
    						<td align="left" width="30%"></td>
    					</tr>
    					<tr>
    						<td align="center" width="30%">联系地址:</td>
    						<td align="center" width="40%">
    							<s:textfield name="jbAddress" id="jbAddress" cssStyle="width:160px;height:24px;" />
    						</td>
    						<td align="left" width="30%">
    							<span id="jbAddressTip">
    								<s:fielderror cssStyle="color:red;padding-left:10px;">
    									<s:param>jbAddress</s:param>
    								</s:fielderror>
    							</span>
    						</td>
    					</tr>
    					<tr>
    						<td align="center" width="30%"><img src="images/new_reg_xing.gif"/>联系手机:</td>
    						<td align="center" width="40%">
    							<s:textfield id="jbPhone" name="jbPhone" cssStyle="width:160px;height:24px;" onblur="checkjbPhone()"/>
    						</td>
    						<td align="left" width="30%">
    							<span id="jbPhoneTip">
    								<s:fielderror cssStyle="color:red;padding-left:10px;">
    									<s:param>jbPhone</s:param>
    								</s:fielderror>
    							</span>
    						</td>
    					</tr>
    					<tr>
    						<td align="center"><img src="images/new_reg_xing.gif"/>短信验证码:</td>
    						<td align="left" colspan="2" style="padding-left: 112px;">
    							<s:textfield id="SmsCheckCode" name="SmsCheckCode" cssStyle="width:80px;height:24px;" maxLength="6" />
    							<span><input type="button" id="btnSendCode" name="btnSendCode" value="免费获取验证码" onclick="sendMessage()" /></span>
    							<span id="SmsCheckCodeTip">
    								<s:fielderror cssStyle="color:red;padding-left:10px;">
    									<s:param>SmsCheckCodeTip</s:param>
    								</s:fielderror>
    							</span>
    						</td>
    					</tr>
    					<tr>
    						<td align="center" width="30%"><img src="images/new_reg_xing.gif"/>证件类型:</td>
    						<td align="center" width="40%">
    						<s:select list="#application.dataMap.get('10002')" label=""
    								headerKey="" headerValue="--请选择--" value="1" listValue="value" onchange="enableCredentialsCode(this)"
    								name="jbCredentialsName" id="jbCredentialsName" cssStyle="width:160px;height:24px;"/>
    						</td>
    						<td align="left" width="30%">
    							<s:fielderror cssStyle="color:red;padding-left:10px;">
    								<s:param>jbCredentialsName</s:param>
    							</s:fielderror>
    						</td>
    					</tr>
    					<tr>
    						<td align="center" width="30%"><img src="images/new_reg_xing.gif"/>证件号码:</td>
    						<td align="center" width="40%">
    							<s:textfield name="jbCredentialsCode" id="jbCredentialsCode" cssStyle="width:160px;height:24px;" onblur="checkjbCredentialsCode()"/>
    						</td>
    						<td align="left" width="30%">
    							<span id="jbCredentialsCodeTip">
    								<s:fielderror cssStyle="color:red;padding-left:10px;">
    									<s:param>jbCredentialsCode</s:param>
    								</s:fielderror>
    							</span>
    						</td>
    					</tr>
    					<tr>
    						<td align="center" width="30%">单位名称:</td>
    						<td align="center" width="40%">
    							<s:textfield name="jbCompanyName" id="jbCompanyName" cssStyle="width:160px;height:24px;" />
    						</td>
    						<td align="left" width="30%">
    							<span id="jbCompanyNameTip">
    								<s:fielderror cssStyle="color:red;padding-left:10px;">
    									<s:param>jbCompanyName</s:param>
    								</s:fielderror>
    							</span>
    						</td>
    					</tr>
    					<tr>
    						<td align="center" width="30%"><img src="images/new_reg_xing.gif"/>所在地区:</td>
    						<td align="center" width="40%">
    						<s:select list="#application.dataMap.get('10003')" label=""
    								headerKey="" headerValue="--请选择--" listKey="key"
    								cssStyle="width:160px;height:24px;" listValue="value" id="jbSourceArea"
    								name="jbSourceArea" onblur="checkjbSourceArea()"/>
    						</td>
    						<td align="left" width="30%">
    							<span id="jbSourceAreaTip">
    								<s:fielderror cssStyle="color:red;padding-left:10px;">
    									<s:param>jbSourceArea</s:param>
    								</s:fielderror>
    							</span>
    						</td>
    					</tr>
    					<tr>
    						<td align="center" width="30%">    <img src="images/new_reg_xing.gif"/>验证码:</td>
    						<td align="center" width="40%">
    							<s:textfield id="checkNum" name="checkNum" cssStyle="width:60px;height:24px;" onblur="checkNumber()" maxLength="4"/>
    							<img id="checkNumImage" src="${pageContext.request.contextPath}/image.jsp">
    							<a onClick="changeCheckNum()" title="点击换一张" style="cursor:hand;"> 换一张</a>
    						</td>
    						<td align="left" width="30%">
    							<span id="checkNumTip">
    								<s:fielderror cssStyle="color:red;padding-left:10px;">
    									<s:param>checkNumTip</s:param>
    								</s:fielderror>
    							</span>
    						</td>
    					</tr>
    					<tr>
    						<td colspan="3" style="vertical-align: top; padding-top: 5px;padding-bottom: 5px;">
    							<input type="submit" value="注册" style="width:50px; height:24px;"/>
    							  
    							<input type="reset" value="重置" style="width:50px; height:24px;"/>
    						</td>
    					</tr>
    				</table>
    			</s:form>
    		</div>
    	</div>
    	<%@include file="/common/buttom.jspf"%>
    </body>
    </html>
    


    三:前台获取短信验证码的js:sms.js

     

     

    var InterValObj; //timer变量,控制时间
    var count = 120; //间隔函数,1秒执行
    var curCount;//当前剩余秒数
    var code = ""; //验证码
    var codeLength = 6;//验证码长度
    
    function sendMessage() {
    	curCount = count;
    	var jbPhone = $("#jbPhone").val();
    	var jbPhoneTip = $("#jbPhoneTip").text();
    	if (jbPhone != "") {
    		if(jbPhoneTip == "√ 该手机号码可以注册,输入正确" || jbPhoneTip == "√ 短信验证码已发到您的手机,请查收"){
    			// 产生验证码
    			for ( var i = 0; i < codeLength; i++) {
    				code += parseInt(Math.random() * 9).toString();
    			}
    			// 设置button效果,开始计时
    			$("#btnSendCode").attr("disabled", "true");
    			$("#btnSendCode").val("请在" + curCount + "秒内输入验证码");
    			InterValObj = window.setInterval(SetRemainTime, 1000); // 启动计时器,1秒执行一次
    			// 向后台发送处理数据
    			$.ajax({
    				type: "POST", // 用POST方式传输
    				dataType: "text", // 数据格式:JSON
    				url: "UserAction_sms.action", // 目标地址
    				data: "jbPhone=" + jbPhone +"&code=" + code,
    				error: function (XMLHttpRequest, textStatus, errorThrown) { 
    					
    				},
    				success: function (data){ 
    					data = parseInt(data, 10);
    					if(data == 1){
    						$("#jbPhoneTip").html("<font color='#339933'>√ 短信验证码已发到您的手机,请查收</font>");
    					}else if(data == 0){
    						$("#jbPhoneTip").html("<font color='red'>× 短信验证码发送失败,请重新发送</font>");
    					}else if(data == 2){
    						$("#jbPhoneTip").html("<font color='red'>× 该手机号码今天发送验证码过多</font>");
    					}
    				}
    			});
    		}
    	}else{
    		$("#jbPhoneTip").html("<font color='red'>× 手机号码不能为空</font>");
    	}
    }
    
    //timer处理函数
    function SetRemainTime() {
    	if (curCount == 0) {                
    		window.clearInterval(InterValObj);// 停止计时器
    		$("#btnSendCode").removeAttr("disabled");// 启用按钮
    		$("#btnSendCode").val("重新发送验证码");
    		code = ""; // 清除验证码。如果不清除,过时间后,输入收到的验证码依然有效
    	}else {
    		curCount--;
    		$("#btnSendCode").val("请在" + curCount + "秒内输入验证码");
    	}
    }
    
    $(document).ready(function() {
    	$("#SmsCheckCode").blur(function() {
    		var SmsCheckCodeVal = $("#SmsCheckCode").val();
    		// 向后台发送处理数据
    		$.ajax({
    			url : "UserAction_checkCode.action", 
    			data : {SmsCheckCode : SmsCheckCodeVal}, 
    			type : "POST", 
    			dataType : "text", 
    			success : function(data) {
    				data = parseInt(data, 10);
    				if (data == 1) {
    					$("#SmsCheckCodeTip").html("<font color='#339933'>√ 短信验证码正确,请继续</font>");
    				} else {
    					$("#SmsCheckCodeTip").html("<font color='red'>× 短信验证码有误,请核实后重新填写</font>");
    				}
    			}
    		});
    	});
    });

     

    四:验证码用户名和手机号码的js:register.js

     

    //去掉前后空格
    function trim(str) {
    	var strnew = str.replace(/^\s*|\s*$/g, "");
    	return strnew;
    }
    //用户名
    function checkusername() {
    	var username = document.form1.username.value;
    	if (username == "" || !isNaN(username.charAt(0))) {
    		document.getElementById("usernameTip").innerHTML = "<font color='red'>× 首字母不能为数字或者用户名不能为空</font>";
    		return false;
    	} else if (username.length < 6 || username.length > 30) {
    		document.getElementById("usernameTip").innerHTML = "<font color='red'>× 用户名长度为6-30位字符</font>";
    		return false;
    	} else {
    		document.getElementById("usernameTip").innerHTML = "<font color='#339933'>√ 用户名合格</font>";
    		// 向后台发送处理数据
    		$.ajax({
    			url : "UserAction_checkUserName.action",// 目标地址
    			data : {username : username}, // 目标参数
    			type : "POST", // 用POST方式传输
    			dataType : "text", // 数据格式:text
    			success : function(data) {
    				data = parseInt(data, 10);
    				if (data != 0) {
    					$("#usernameTip").html("<font color='red'>× 该用户名已经被注册,请重新输入</font>");
    				} else {
    					$("#usernameTip").html("<font color='#339933'>√ 该用户名可以注册,输入正确</font>");
    				}
    			}
    		});
    		return true;
    	}
    }
    // 登录密码
    function checkpassword() {
    	var password = document.form1.password.value;
    	if (password.length < 6 || password.length > 30) {
    		document.getElementById("passwordTip").innerHTML = "<font color='red'>× 密码长度不能小于6位,大于30位</font>";
    		return false;
    	} else if (!isNaN(password)) {
    		document.getElementById("passwordTip").innerHTML = "<font color='red'>× 密码不能全是数字</font>";
    		return false;
    	} else {
    		document.getElementById("passwordTip").innerHTML = "<font color='#339933'>√ 密码合格</font>";
    		return true;
    	}
    }
    // 确认密码
    function checkpasswrodb() {
    	var password = document.form1.password.value;
    	var passwordRepeat = document.form1.passwordRepeat.value;
    	if (trim(password) != trim(passwordRepeat)) {
    		document.getElementById("passwordRepeatTip").innerHTML = "<font color='red'>× 两次密码输入必须一致</font>";
    		return false;
    	} else {
    		document.getElementById("passwordRepeatTip").innerHTML = "<font color='#339933'>√ 密码输入一致</font>";
    		return true;
    	}
    }
    // 姓名
    function checknickname() {
    	var nickname = document.form1.nickname.value;
    	if (trim(nickname) == "") {
    		document.getElementById("nicknameTip").innerHTML = "<font color='red'>× 姓名不能为空</font>";
    		return false;
    	} else {
    		document.getElementById("nicknameTip").innerHTML = "<font color='#339933'>√ 姓名输入正确</font>";
    		return true;
    	}
    }
    // 联系手机(ajax验证手机号码是否已经存在)
    function checkjbPhone() {
    	var jbPhone = document.form1.jbPhone.value;
    	var re= /(^1[3|5|8][0-9]{9}$)/;
    	if (trim(jbPhone) == "") {
    		document.getElementById("jbPhoneTip").innerHTML = "<font color='red'>× 手机号码不能为空</font>";
    		return false;
    	} else if(trim(jbPhone) != ""){
    		if(!re.test(jbPhone)){
    			document.getElementById("jbPhoneTip").innerHTML = "<font color='red'>× 请输入有效的手机号码</font>";
    			return false;
    		}else{
    			document.getElementById("jbPhoneTip").innerHTML = "<font color='#339933'>√ 手机号码输入正确</font>";
    			// 向后台发送处理数据
    			$.ajax({
    				url : "UserAction_checkPhone.action",// 目标地址
    				data : {jbPhone : jbPhone}, // 目标参数
    				type : "POST", // 用POST方式传输
    				dataType : "text", // 数据格式:text
    				success : function(data) {
    					data = parseInt(data, 10);
    					if (data != 0) {
    						$("#jbPhoneTip").html("<font color='red'>× 该手机号码已经被注册,请重新输入</font>");
    					} else {
    						$("#jbPhoneTip").html("<font color='#339933'>√ 该手机号码可以注册,输入正确</font>");
    					}
    				}
    			});
    			return true;
    		}
    	}
    	
    }
    // 证件号码
    function checkjbCredentialsCode() {
        var jbCredentialsCode = document.form1.jbCredentialsCode.value;
        var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/; 
    	if (trim(jbCredentialsCode) == "") {
    		document.getElementById("jbCredentialsCodeTip").innerHTML = "<font color='red'>× 证件号码不能为空</font>";
    		return false;
    	} else if(trim(jbCredentialsCode) != ""){
    		if(!reg.test(jbCredentialsCode)){
    			document.getElementById("jbCredentialsCodeTip").innerHTML = "<font color='red'>× 请输入合法的证件号码</font>";
    			return false;
    		}else{
    			document.getElementById("jbCredentialsCodeTip").innerHTML = "<font color='#339933'>√ 证件号码输入正确</font>";
    			// 向后台发送处理数据
    			$.ajax({
    				url : "UserAction_checkCredentialsCode.action",// 目标地址
    				data : {jbCredentialsCode : jbCredentialsCode}, // 目标参数
    				type : "POST", // 用POST方式传输
    				dataType : "text", // 数据格式:text
    				success : function(data) {
    					data = parseInt(data, 10);
    					if (data != 0) {
    						$("#jbCredentialsCodeTip").html("<font color='red'>× 该证件号码已经被注册,请重新输入</font>");
    					} else {
    						$("#jbCredentialsCodeTip").html("<font color='#339933'>√ 该证件号码可以注册,输入正确</font>");
    					}
    				}
    			});
    			return true;
    		}
    	}
    }
    // 所在地区
    function checkjbSourceArea() {
    	var jbSourceArea = document.form1.jbSourceArea.value;
    	if (trim(jbSourceArea) == "") {
    		document.getElementById("jbSourceAreaTip").innerHTML = "<font color='red'>× 请选择所在地区</font>";
    		return false;
    	} else {
    		document.getElementById("jbSourceAreaTip").innerHTML = "<font color='#339933'>√ 所在地区选择正确</font>";
    		return true;
    	}
    }
    // 验证码
    function checkNumber() {
    	var checkNum = document.form1.checkNum.value;
    	if (trim(checkNum) == "") {
    		document.getElementById("checkNumTip").innerHTML = "<font color='red'>× 验证码不能为空</font>";
    		return false;
    	} else {
    		document.getElementById("checkNumTip").innerHTML = "<font color='#339933'>√ 验证码合格</font>";
    		// 向后台发送处理数据
    		$.ajax({
    			url : "UserAction_checkNum.action",// 目标地址
    			data : {checkNum : checkNum}, // 目标参数
    			type : "POST", // 用POST方式传输
    			dataType : "text", // 数据格式:text
    			success : function(data) {
    				data = parseInt(data, 10);
    				if (data != 0) {
    					$("#checkNumTip").html("<font color='red'>× 验证码错误</font>");
    				} else {
    					$("#checkNumTip").html("<font color='#339933'>√ 验证码正确</font>");
    				}
    			}
    		});
    		return true;
    	}
    }

     

     

    五:后台action的代码:UserAction.java(这里只是调用了我们的第三方给提供的客户端代码的发送短信的方法,如果是调用其他的短信平台,可以换成他们的发送短信的方法,这里只是给大家做个参考)

     

     

    package cn.gov.csrc.base.systemmanager.action;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.List;
    
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.log4j.Logger;
    import org.apache.struts2.convention.annotation.Action;
    import org.apache.struts2.convention.annotation.Result;
    import org.apache.struts2.convention.annotation.Results;
    import org.springframework.context.annotation.Scope;
    import org.springframework.security.authentication.encoding.MessageDigestPasswordEncoder;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.stereotype.Controller;
    
    import cn.gov.csrc.base.action.BaseAction;
    import cn.gov.csrc.base.log.service.LogService;
    import cn.gov.csrc.base.report.util.CommonUtil;
    import cn.gov.csrc.base.report.util.Env;
    import cn.gov.csrc.base.systemmanager.model.Count;
    import cn.gov.csrc.base.systemmanager.model.User;
    import cn.gov.csrc.base.systemmanager.service.CountService;
    import cn.gov.csrc.base.systemmanager.service.UserService;
    import cn.gov.csrc.base.util.WebContextUtil;
    
    import com.sms.webservice.client.SmsReturnObj;
    import com.sms.webservice.client.SmsWebClient;
    /**
     * File: UserAction.java 
     * Author: jiangsai 
     * Version: 1.1 
     * Date: 04/17/2013 
     * Modify:
     * Description:用户 
     * Copyright csrc
     */
    @Controller()
    @Scope("prototype")
    @Results({
    		@Result(name = "success", location = "/statics/report.jsp"),
    		@Result(name = "modifyPassword", location = "/statics/modifyPassword.jsp")
    		})
    public class UserAction extends BaseAction<User> {
    	
    	private static final long serialVersionUID = 1214696686677691191L;
    	private static Logger log = Logger.getLogger(UserAction.class);
    	private static final String url = Env.getInstance().getProperty("url");
    	private static final String userName = Env.getInstance().getProperty(
    			"username");
    	private static final String passWord = Env.getInstance().getProperty(
    			"password");
    
    	private Integer id;
    
    	private String username;// 用户名
    
    	private String password;// 密码
    
    	private String passwordRepeat;// 确认密码
    	
    	private String jbPhone;//手机号码
    	
    	private String jbCredentialsCode;//身份证号码
    	
    	private String checkNum;//图片验证码
    
    	private String newPassword;
    
    	private String confirmPassword;
    
    	private Integer[] ownRoleIds;
    
    	private UserService userService;
    	
    	private CountService countService;
    	
    	private LogService logService;
    	
    	private Count count = new Count();
    
    	public Integer getId() {
    		return id;
    	}
    
    	public void setId(Integer id) {
    		this.id = id;
    	}
    
    	public String getUsername() {
    		return username;
    	}
    
    	public void setUsername(String username) {
    		this.username = username;
    	}
    
    	public String getPassword() {
    		return password;
    	}
    
    	public void setPassword(String password) {
    		this.password = password;
    	}
    
    	public String getPasswordRepeat() {
    		return passwordRepeat;
    	}
    
    	public void setPasswordRepeat(String passwordRepeat) {
    		this.passwordRepeat = passwordRepeat;
    	}
    	
    	public String getJbPhone() {
    		return jbPhone;
    	}
    
    	public void setJbPhone(String jbPhone) {
    		this.jbPhone = jbPhone;
    	}
    	
    	public String getJbCredentialsCode() {
    		return jbCredentialsCode;
    	}
    
    	public void setJbCredentialsCode(String jbCredentialsCode) {
    		this.jbCredentialsCode = jbCredentialsCode;
    	}
    
    	public String getCheckNum() {
    		return checkNum;
    	}
    
    	public void setCheckNum(String checkNum) {
    		this.checkNum = checkNum;
    	}
    
    	public Integer[] getOwnRoleIds() {
    		return ownRoleIds;
    	}
    
    	public void setOwnRoleIds(Integer[] ownRoleIds) {
    		this.ownRoleIds = ownRoleIds;
    	}
    
    	public String getNewPassword() {
    		return newPassword;
    	}
    
    	public void setNewPassword(String newPassword) {
    		this.newPassword = newPassword;
    	}
    
    	public String getConfirmPassword() {
    		return confirmPassword;
    	}
    
    	public void setConfirmPassword(String confirmPassword) {
    		this.confirmPassword = confirmPassword;
    	}
    
    	@Resource
    	public void setUserService(UserService userService) {
    		this.userService = userService;
    	}
    
    	public UserService getUserService() {
    		return userService;
    	}
    
    	@Resource
    	public void setCountService(CountService countService) {
    		this.countService = countService;
    	}
    
    	public CountService getCountService() {
    		return countService;
    	}
    	
    	public LogService getLogService() {
    		return logService;
    	}
    
    	@Resource
    	public void setLogService(LogService logService) {
    		this.logService = logService;
    	}
    
    	public Count getCount() {
    		return count;
    	}
    
    	public void setCount(Count count) {
    		this.count = count;
    	}
    
    	public void prepareToUpdatePage() {
    		model = userService.getEntity(id);
    	}
    	
    	/**
    	 * 用户登录
    	 * 
    	 * @return success
    	 */
    	@Action(value = "UserAction_login")
    	public String login() {
    		Object u = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    		if (u instanceof User && u != null) {
    			WebContextUtil.getSession().setAttribute("user", u);
    			User user = (User)u;
    			//使用数据库表TBL_BASE_LOG添加用户登录的日志信息
    			logService.saveTblBaseLog(WebContextUtil.getRequest(),"当前操作人【"+user.getNickname()+"】登录系统");
    		} else {
    			// 防止绕过登陆页面直接执行Action
    			return "login";
    		}
    		return SUCCESS;
    	}
    	
    	/**
    	 * 用户密码更新
    	 */
    	@Action(value = "UserAction_updateUser")
    	public String updateUser() {
    		if (!newPassword.equals(confirmPassword)) {
    			this.setMessage("新密码与确认密码不一致!");
    			return "modifyPassword";
    		}
    		User u = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    		MessageDigestPasswordEncoder encoder = new MessageDigestPasswordEncoder("md5");
    		String psw = encoder.encodePassword(newPassword, null);
    		userService.modifyPassword(u, psw);
    		this.setMessage("保存成功!");
    		return "modifyPassword";
    	}
    	
    	/**
    	 * 验证用户名是否存在
    	 * 
    	 * @throws Exception
    	 */
    	@Action(value = "UserAction_checkUserName")
    	public void checkUserName(){
    		String result = "0";
    		try {
    			List<User> list = userService.findUserByUserName(username);
    			if(list != null && list.size() > 0){
    				result = "1";
    			}else{
    				result = "0";
    			}
    			HttpServletResponse response = WebContextUtil.getResponse();
    			response.setContentType("application/json;charset=UTF-8");
    			response.setHeader("Cache-Control", "no-cache");
    			PrintWriter out = response.getWriter();
    			out.write(result.toString());
    		} catch (IOException e) {
    			throw new RuntimeException("验证身份证号码出错", e);
    		}
    	}
    
    	/**
    	 * 验证原始密码是否正确
    	 * 
    	 * @throws Exception
    	 */
    	@Action(value = "UserAction_checkPassWord")
    	public void checkPassWord() throws Exception {
    		String result = "0";
    		MessageDigestPasswordEncoder encoder = new MessageDigestPasswordEncoder("md5");
    		String pwd = encoder.encodePassword(password, null);
    		List<User> user = userService.findUserByPassWord(pwd);
    		if (user != null && user.size() > 0) {
    			result = "1";
    		}else{
    			result = "0";
    		}
    		HttpServletResponse response = WebContextUtil.getResponse();
    		response.setContentType("application/json;charset=UTF-8");
    		response.setHeader("Cache-Control", "no-cache");
    		PrintWriter out = response.getWriter();
    		out.write(result.toString());
    	}
    	
    	/**
    	 * 验证手机号码是否存在
    	 */
    	@Action(value = "UserAction_checkPhone")
    	public void checkPhone(){
    		String result = "0";
    		try {
    			List<User> list = userService.findUserByPhone(jbPhone);
    			if(list != null && list.size() > 0){
    				result = "1";
    			}else{
    				result = "0";
    			}
    			HttpServletResponse response = WebContextUtil.getResponse();
    			response.setContentType("application/json;charset=UTF-8");
    			response.setHeader("Cache-Control", "no-cache");
    			PrintWriter out = response.getWriter();
    			out.write(result.toString());
    		} catch (IOException e) {
    			throw new RuntimeException("验证手机号码出错", e);
    		}
    	}
    	
    	/**
    	 * 验证身份证号码是否存在
    	 */
    	@Action(value = "UserAction_checkCredentialsCode")
    	public void checkCredentialsCode(){
    		String result = "0";
    		try {
    			List<User> list = userService.findUserByCredentialsCode(jbCredentialsCode);
    			if(list != null && list.size() > 0){
    				result = "1";
    			}else{
    				result = "0";
    			}
    			HttpServletResponse response = WebContextUtil.getResponse();
    			response.setContentType("application/json;charset=UTF-8");
    			response.setHeader("Cache-Control", "no-cache");
    			PrintWriter out = response.getWriter();
    			out.write(result.toString());
    		} catch (IOException e) {
    			throw new RuntimeException("验证身份证号码出错", e);
    		}
    	}
    	
    	/**
    	 * 验证验证码是否正确
    	 */
    	@Action(value = "UserAction_checkNum")
    	public void checkNum(){
    		try {
    			String result = "0";
    			String check_number_key = (String)WebContextUtil.getSession().getAttribute("CHECK_NUMBER_KEY");
    			if(checkNum != check_number_key && !checkNum.equals(check_number_key)){
    				result = "1";
    			}else{
    				result = "0";
    			}
    			HttpServletResponse response = WebContextUtil.getResponse();
    			response.setContentType("application/json;charset=UTF-8");
    			response.setHeader("Cache-Control", "no-cache");
    			PrintWriter out = response.getWriter();
    			out.write(result.toString());
    		} catch (IOException e) {
    			throw new RuntimeException("验证验证码出错", e);
    		}
    	}
    	
    	/**
    	 * 验证短信验证码是否正确
    	 * 
    	 * @throws Exception
    	 */
    	@Action(value = "UserAction_checkCode")
    	public void checkCode() throws Exception{
    		String result = "0";
    		/** 获取手动输入的手机短信验证码 */
    		String SmsCheckCode = WebContextUtil.getRequest().getParameter("SmsCheckCode");
    		/** 获取session中存放的手机短信验证码 */
    		String code = (String) WebContextUtil.getSession().getAttribute("code");
    		try {
    			if(SmsCheckCode != code && !SmsCheckCode.equals(code)){
    				result = "0";
    			}else{
    				result = "1";
    			}
    		} catch (Exception e) {
    			throw new RuntimeException("短信验证失败", e);
    		}
    		HttpServletResponse response = WebContextUtil.getResponse();
    		response.setContentType("application/json;charset=UTF-8");
    		response.setHeader("Cache-Control", "no-cache");
    		PrintWriter out = response.getWriter();
    		out.write(result.toString());
    	}
    	
    	/**
    	 * 验证手机短信是否发送成功
    	 * 
    	 * @throws Exception
    	 */
    	@Action(value = "UserAction_sms")
    	public void sms() throws Exception {
    		String result = "0";
    		/** 手机号码 */
    		String jbPhone = WebContextUtil.getRequest().getParameter("jbPhone");
    		/** 短信验证码 */
    		String code = WebContextUtil.getRequest().getParameter("code");
    		/** 短信验证码存入session(session的默认失效时间30分钟) */
    		WebContextUtil.getSession().setAttribute("code", code);
    		/** 如何初始化失败返回 */
    		if(!initClient()) {
    			return;
    		}
    		/** 单个手机号发送短信的方法的参数准备 */
    		// 手机号码
    		String mobilephone = jbPhone;
    		// 短信内容+随机生成的6位短信验证码
    		String content = "根据中国证监会举报中心委托,特向您发送此条短信。您的注册验证码为:" + code;
    		// 操作用户的ID
    		Integer operId = Integer.parseInt(Env.getInstance().getProperty("operId"));
    		// 定时发送的的发送时间(缺省为空,如果即时发送,填空)
    		String tosend_time = "";
    		// 应用系统的短信ID,用户查询该短信的状态报告(缺省为0,即不需查询短信的状态报告)
    		int sms_id = 0;
    		// 黑名单过滤(0:不需要黑名单过滤,1:需要黑名单过滤,缺省为0)
    		short backlist_filter = 0;
    		// 禁止语过滤(0:不需要禁止语过滤,1:需要禁止语过滤,缺省为0)
    		short fbdword_filter = 0;
    		// 优先级(值越大优先级越高,0:普通,1,:优先,2:最高,缺省为0)
    		short priority = 0;
    		// 短信有效时间(格式为:YYYY-MM-DD HH:mm:ss目前为空)
    		String valid_time = "";
    		/** 发送短信之前先统计一个已经发送的短信条数 */
    		int messageCount = countService.findAllRecord(mobilephone);
    		log.info("已发短信条数为:" +messageCount);
    		if(messageCount < 5){
    			/** 单个手机号发送短信 */
    			if (!sendMessage(mobilephone, content, operId, tosend_time, sms_id,
    					backlist_filter, fbdword_filter, priority, valid_time)) {
    				result = "0";// 失败
    			} else {
    				result = "1";// 成功
    				/** 发送一条短信,记录一条短信记录,为了方便之后的统计短信发送次数 */
    				count.setPhone(mobilephone);// 手机号码
    				count.setCaptcha(code);// 短信验证码
    				count.setSendTime(CommonUtil.getNowDate());// 短信发送时间
    				if(count != null){
    					countService.saveEntity(count);
    					log.info("短信验证码发送记录保存成功!");
    				}
    			}
    		}else{
    			result = "2";//一个手机号码最多发送5条短信验证码
    			log.info("该手机号码今天发送验证码过多");
    		}
    		HttpServletResponse response = WebContextUtil.getResponse();
    		response.setContentType("application/json;charset=UTF-8");
    		response.setHeader("Cache-Control", "no-cache");
    		PrintWriter out = response.getWriter();
    		out.write(result.toString());
    	}
    	
    	/**
    	 * WebService客户端初始化
    	 * 
    	 */
    	public static boolean initClient() {
    		/**
    		 * 判断客户端是否已经初始化
    		 */
    		if (!SmsWebClient.enable()) {
    			int ret = 0;
    			try {
    				ret = SmsWebClient.init(url, userName, passWord);
    				if (ret == -1 || !SmsWebClient.enable()) {
    					log.info("短信平台接口初始化失败!");
    					return false;
    				}
    				log.info("短信平台接口初始化成功!" + ret + "-----");
    			} catch (Exception ex) {
    				ex.printStackTrace();
    				log.info("短信平台接口初始化过程中异常!");
    			}
    		}
    		return true;
    	}
    	
    	/**
    	 * 单个手机号码发送
    	 * 
    	 * @param mobilephone
    	 *            手机号
    	 * @param content
    	 *            短信内容
    	 * @param operId
    	 *            操作用户的ID
    	 * @param tosend_time
    	 *            定时发送的发送时间
    	 * @param sms_id
    	 *            应用系统的短信ID
    	 * @param backlist_filter
    	 *            黑名单过滤
    	 * @param fbdword_filter
    	 *            禁止语过滤
    	 * @param priority
    	 *            优先级
    	 * @param valid_time
    	 *            短信有效时间
    	 */
    	public static boolean sendMessage(java.lang.String mobilephone,
    			java.lang.String content, int operId, java.lang.String tosend_time,
    			int sms_id, short backlist_filter, short fbdword_filter,
    			short priority, java.lang.String valid_time) {
    		// 单个手机号码发送
    		try {
    			SmsReturnObj retObj = SmsWebClient.webSendMessage(mobilephone,
    					content, operId, tosend_time, sms_id, backlist_filter,
    					fbdword_filter, priority, valid_time);
    			if (retObj.getReturnCode() != 1) {
    				log.info("短信发送失败,原因为:" + retObj.getReturnMsg());
    				return false;
    			} else {
    				log.info("短信发送成功!返回结果为:" + retObj.getReturnMsg());
    				return true;
    			}
    		} catch (Exception ex) {
    			ex.printStackTrace();
    			log.info("短信发送过程发生异常!");
    		}
    		return true;
    	}
    	
    	
    }
    

     

     

     

     

     

    六:具体的短信接口demo到这里下,这里你下载了也不能成功的发送短信,因为你必须要短信平台商给你提供:url,userName,passWord,operId,以及短信平台商还要绑定你的外网ip地址,这样才能真正的发送短信。

    Demo下载链接: http://pan.baidu.com/s/1qWt1Qdm

     

    原文:http://www.zuidaima.com/share/1881657001233408.htm

    七:最后,如果有小伙伴在学习的过程中有问题,可以添加楼主微信,楼主会尽量抽时间帮你解决遇到的问题;

    八:如果还是没解决,可以加入QQ交流群讨论解决:

     

    展开全文
  • 手机验证码生成

    2018-07-31 15:17:15
    手机验证码生成 /**  * 描述:手机验证码生成带字符,包含数字和字符  *  * @param len  * 生成手机验证码长度  * @return  */  public static String identifyingCode(int len) {  char[] identifyStr = ...

    手机验证码生成

    /**
         * 描述:手机验证码生成带字符,包含数字和字符
         *
         * @param len
         *            生成手机验证码长度
         * @return
         */
        public static String identifyingCode(int len) {
            char[] identifyStr = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
                    'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
            // char[] identifyStr={'0','1','2','3','4','5','6','7','8','9'};
            // 生成随机类
            // Random random = new Random();
            int min = 0;
            int maxnum = identifyStr.length;
            String codeStr = "";
            for (int i = 0; i < len; i++) {
                int num = (int) ((maxnum - min) * Math.random() + min);
                codeStr += identifyStr[num];
            }
            return codeStr;
        }

    可以生成随机验证码。这个方法可以放到你们的工具包里,以方便以后使用!

     

     

    展开全文
  • 手机验证码设计表

    2018-10-18 15:30:31
    包括发送手机验证码,有效时间,验证有效性以及每个手机号的总发送次数。
  • 手机验证码demo.rar

    2020-05-20 22:34:38
    手机验证码demo,各个网站制作都需要手机验证码,这个验证码完成主要是使用了网站提供的接口,demo中注释已备注
  • 目前最好的手机验证码平台就是爱码与飞Q,已经集成模块,有祥细的说明。每次用网页访问太烦人了,就集成了模块,现放出供大家便用.
  • 用java技术实现登录注册手机验证码!注册一个秒滴平台获取里面的信息配合代码,就可以实现手机验证码的验证,下载导入进去就可以用
  • 如果验证码是手机验证码请求,向页面传验证码,又要把验证码通过AJAX把值请求道聚合数据,这样一来就有两个AJAX,我不知道怎么处理。当然聚合数据短信验证不支持跨域访问,但是如果可以,怎么处理两个AJAX的运行和...
  • java实现发送手机验证码功能

    万次阅读 多人点赞 2018-07-04 11:03:32
    需要在秒嘀上新建一个发送手机验证码的模板,点击 配置管理 -> 验证码短信模板,就会进入如下界面 5. 点击“新建模板”按钮, 填写好模板名称、短信签名 和 短信内容(短信内容可以选择 验证码通知短信模板 或者 ...
  • php手机验证码

    2014-08-21 17:17:25
    用户注册网站时,通过输入手机号码,获取验证码注册网站或商城
  • java发送手机验证码

    2017-09-18 23:16:13
    java发送手机验证码,//生成1个六位数随机数,将验证码添加到session中,网络编程,请求云服务器,实现验证码的发送
  • 手机验证码软件

    2014-08-17 13:07:05
    手机验证码,自动回复软件,不再手动回复,真正全自动验证,
  • js发送手机验证码

    2015-06-29 18:00:33
    js发送手机验证码ajax前后端交互
  • jquery手机验证码登陆

    2021-06-01 19:39:57
    简单的移动端手机号码验证码倒计时
  • 表结构:https://download.csdn.net/download/weixin_42330073/10848493 &lt;?... /** * 发送手机验证码 */ public function sendMobileCode() { Db::startTrans(); $mobile = $this-&g...
  • 手机验证码测试点

    千次阅读 2018-01-23 18:13:00
    手机短信认证测试点1,输入手机号码,待收到手机验证码后,更改原来手机号码,输入验证码,提示:失败(注意这个漏测了)2,输入手机号码,待收到手机验证码后,输入验证码 ,成功3,输入手机号码,待收到手机验证码后,...
  • 微信小程序手机验证码,代码简洁,容易

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 53,602
精华内容 21,440
关键字:

如何看手机验证码