前端常见的【手机验证码】【图片验证码】功能实现-前后端配合实现


<div className={styles.psw} style={{ height: '540px' }}>

          <div className={styles.pswTitle}>找回密码</div>

          <div className={styles.line1}></div>

          <div className={styles.line2}></div>

          <div>

            <Form layout="inline">

              <div className={styles.inputW}>

                <div>

                  <div className={styles.iconPosition}>

                    <img

                      src={usericon}

                      alt=""

                      style={{ width: '15px', height: '20px' }}

                    />

                    <span className={styles.inputText}>

                      <span style={{ color: 'red' }}>*</span>用户名

                    </span>

                  </div>

                  <FormItem>

                    {getFieldDecorator('userName', {

                      rules: [

                        {

                          required: true,

                          message: '请输入用户名'

                        }

                      ]

                    })(<Input placeholder="请输入用户名" />)}

                  </FormItem>

                </div>

              </div>

              <div className={styles.inputW}>

                <div>

                  <div className={styles.iconPosition}>

                    <img

                      src={phoneIcon}

                      alt=""

                      style={{ width: '15px', height: '20px' }}

                    />

                    <span className={styles.inputText}>

                      <span style={{ color: 'red' }}>*</span>手机号

                    </span>

                  </div>

                  <FormItem>

                    {getFieldDecorator('mobile', {

                      rules: [

                        {

                          required: true,

                          pattern: /^1[34578]\d{9}$/,

                          message: '请输入正确的手机号码'

                        }

                      ]

                    })(<Input placeholder="请输入手机号" />)}

                  </FormItem>

                </div>

              </div>



              <div className={styles.inputW}>

                <div>

                  <div className={styles.iconPosition}>

                    <img

                      src={passwordIcon}

                      alt=""

                      style={{ width: '15px', height: '20px' }}

                    />

                    <span

                      className={styles.inputText}

                      style={{ width: '70px' }}

                    >

                      <span style={{ color: 'red' }}>*</span>设置密码

                    </span>

                  </div>

                  <FormItem>

                    {getFieldDecorator('password', {

                      rules: [

                        {

                          required: true,

                          message: '请输入6-16位字符和数字组合,字符区分大小写',

                          // eslint-disable-next-line

                          pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$/

                        },

                        { validator: validateToNextPassword }

                      ]

                    })(<Input.Password placeholder="请输入密码" />)}

                  </FormItem>

                </div>

              </div>

              <div className={styles.inputW}>

                <div>

                  <div className={styles.iconPosition}>

                    <img

                      src={passwordIcon}

                      alt=""

                      style={{ width: '15px', height: '20px' }}

                    />

                    <span

                      className={styles.inputText}

                      style={{ width: '70px' }}

                    >

                      <span style={{ color: 'red' }}>*</span>确认密码

                    </span>

                  </div>

                  <FormItem>

                    {getFieldDecorator('comfirm', {

                      rules: [

                        { required: true, message: '请输入确认密码' },

                        { validator: compareToFirstPassword }

                      ]

                    })(

                      <Input.Password

                        onBlur={handleConfirmBlur}

                        placeholder="请再次输入密码"

                      />

                    )}

                  </FormItem>

                </div>

              </div>

              <div className={styles.inputW1} style={{ position: 'relative' }}>

                <div>

                  <div className={styles.iconPosition}>

                    <img

                      src={check}

                      alt=""

                      style={{ width: '15px', height: '20px' }}

                    />

                    <span

                      className={styles.inputText}

                      style={{ width: '70px' }}

                    >

                      <span style={{ color: 'red' }}>*</span>短信验证

                    </span>

                  </div>

                  <YZMButton

                    onClick={onclick}

                    time={time}

                    className={styles.yzmc}

                  />

                  <FormItem>

                    {getFieldDecorator('smsCode', {

                      rules: [

                        {

                          required: true,

                          message: '请输入'

                        }

                      ]

                    })(<Input placeholder="请输入验证码" />)}

                  </FormItem>

                </div>

              </div>



              <div className={styles.button} style={{ margin: '30px 50px' }}>

                <Button

                  onClick={() => {

                    window.history.back()

                  }}

                  className={styles.backButton}

                >

                  返回

                </Button>

                <Button onClick={handlOnsave} className={styles.findButton}>

                  找回密码

                </Button>

              </div>

            </Form>

          </div>

        </div>

(2)使用验证码组件YZMButton


import React, { useCallback, useState, useRef } from 'react'

import styles from './index.less'

import classnames from 'classnames'

import { Button } from 'antd'

interface YZMButtonProps {

  onClick: (e: any) => any

  time: number

  text?: string

  className: any

}



export default function YZMButton({

  onClick,

  time,

  text,

  className

}: YZMButtonProps) {

  const [yzime, setYzime] = useState(time)

  const _yzime = useRef(yzime)

  _yzime.current = yzime

  const flag = yzime === time

  const handleClick = useCallback(

    (e: any) => {

      if (flag) {

        if (!onClick(e)) {

          return

        }

        let timer = setInterval(() => {

          if (_yzime.current === 0) {

            clearInterval(timer)

            setYzime(time)

          } else {

            setYzime(value => value - 1)

          }

        }, 1000)

      }

    },

    [flag, onClick, time]

  )



  return (

    <Button

      className={classnames(styles.content, className)}

      onClick={handleClick}

      disabled={!flag}

    >

      {flag ? text || '获取验证码' : `还剩${yzime}s`}

    </Button>

  )

}



点击按钮之后,按钮变成不可用状态,与此同时60秒倒计时开始。

(3)调接口获取验证码

在click方法中,调用后端提供的方法获取短信验证码


const onclick = useCallback(() => {

    let callbackRes = true

    validateFields(['mobile'], (err: any, fieldsValue: any) => {

      if (err) {

        callbackRes = false

      }

      let { mobile } = fieldsValue

      let res = {

        mobile: mobile,

        type: 'forget-password'

      }

      dispatch({

        type: 'login/getyzm',

        params: [res]

      }).then((v: any) => {

        if (v.code === -1) {

          message.error(v.message)

          callbackRes = false

        } else if (v.code === 500) {

          message.error(v.message)

          callbackRes = false

        } else {

          callbackRes = true

        }

      })

    })

    return callbackRes

  }, [dispatch, validateFields])

(4)提交表单 找回密码


  const handlOnsave = useCallback(() => {

    validateFields((err: any, fieldsValue: any) => {

      if (err) return

      let res = {

        userName: fieldsValue.userName,

        mobile: fieldsValue.mobile,

        // password: btoa(fieldsValue.password),

        newPassword: fieldsValue.password,

        code: fieldsValue.smsCode

      }

      dispatch({

        type: 'login/getback',

        params: [res]

      }).then((v: any) => {

        if (v.code === 200) {

          message.info(v.message)

          window.location.href = '/#/login/password'

        } else {

          message.info(v.message)

        }

      })

    })

  }, [dispatch, validateFields])

二、图片验证码功能

=========

1. 实现思路

进入页面,前端向后端发送请求(需要UUID),获取一张二维码,之后提交表单的同时提交uuid和验证码,后端请求验证。后端使用到阿里的获取短信验证码的服务。

2. 后端接口

后端需要拿到uuid借助阿里的生成图片验证码的工具进行生成,并将图片验证码返回给前端。最后,需要借助前端提交的uuid和验证码信息进行比对,即可实现提交功能。

3. 前端实现

(1)使用uuid

UUID 是 通用唯一识别码.

安装依赖:npm install uuid

引入依赖:import { v4 as uuidv4 } from "uuid

生成uuid使用方法:const id =uuidv4()

console.log(id)

e6a2f201-f720-4e98-8fea-7f473101acd3

(2)进入页面获取验证码图片


  const getCode = useCallback(() => {

    let id = uuidv4()

    setUuid(id)

    let result = dispatch({

      type: 'global/get1',

      params: ['/uaa/captcha.jpg', { uuid: id }]

    })

    console.log(result)

    return result

  }, [dispatch, setUuid])



  useEffect(() => {

    getCode().then((v: any) => {

      let a = window.URL.createObjectURL(v)

      setCode(a)

    })

  }, [getCode])

生成图片的请求需要向后端提供一个uuid.

注意 这里的请求就是/uaa/captcha.jpg  你没有看错。

(3)处理后端返回的图片并显示

请求之后后端返回的是一张图片,注意是一张图片,而不是图片的url.

文末

逆水行舟不进则退,所以大家要有危机意识。

同样是干到35岁,普通人写业务代码划水,榜样们深度学习拓宽视野晋升管理。

这也是为什么大家都说35岁是程序员的门槛,很多人迈不过去,其实各行各业都是这样都会有个坎,公司永远都缺的高级人才,只用这样才能在大风大浪过后,依然闪耀不被公司淘汰不被社会淘汰。

为了帮助大家更好温习重点知识、更高效的准备面试,特别整理了《前端工程师核心知识笔记》电子稿文件。

内容包括html,css,JavaScript,ES6,计算机网络,浏览器,工程化,模块化,Node.js,框架,数据结构,性能优化,项目等等。

269页《前端大厂面试宝典》

包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。

前端面试题汇总

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值