用 Line LIFF APP 实现信箱验证绑定功能(4) - 表单验证电子邮件地址

前几天完成了一个简单发送认证码的 LIFF APP,其实还有很多可以优化的地方,像是在送出 Request 前,需要先检查使用者输入的是否为有效的电子邮件地址,以及提供过一段时间後重新发送的功能。

判断电子邮件地址是否合法

要判断一个电子邮件地址是否合法,必须要先知道电子邮件地址是由三个部分组成的 {local}@{domain}

  • local:
    • 最多64个字元
    • 通用接受 A-Z, a-z, 0-9, 但大写字母在某些邮件服务器可能被拒绝,或者一律视为小写
    • 接受 . 但不能出现在首尾,也不能连续出现(若在引号内则不受限制)
    • 接受大部分的 ASCII Graphic Char,但实际能否使用还是要看邮件服务器的限制
    • 在某些邮件服务器 +- 後面的字元可忽略,也就是说只要 +- 前面的字元相同,便有可能指向同一个收件地址
  • @: 分隔 local & domain
  • domain:
    • 最多255个字元
    • 必须符合严格的主机域名规则:一个以点分隔的DNS标签序列,每个标签被限定为长度不超过63个字元
    • 通用接受 A-Z, a-z, 0-9, -,其中 - 不能出现在首尾,且顶级域名不可全部由数字组成。

以上是大略统整的规则,更详细的规则可参考 RFC 5322 (3.2.3 & 3.4.1), RFC 5321RFC 3696,网路上也有很多整理好的 RFC 简易原则文章。

看完以上这段,就可以发现如果要重新打造一个精准验证电子邮件地址是否合法的判断式,是非常复杂且耗时的一件事,为了不重复造轮子,这边还是使用套件进行验证吧~

使用套件 - yup

yup 是一个 JavaScript 的内容验证套件,有不少套件或框架已经在使用它。

Yup is a JavaScript schema builder for value parsing and validation. Define a schema, transform a value to match, validate the shape of an existing value, or both. Yup schema are extremely expressive and allow modeling complex, interdependent validations, or value transformations.

Yup's API is heavily inspired by Joi, but leaner and built with client-side validation as its primary use-case. Yup separates the parsing and validating functions into separate steps. cast() transforms data while validate checks that the input is the correct shape. Each can be performed together (such as HTML form validation) or seperately (such as deserializing trusted data from APIs).

要使用就必须先在我们的 Vue Project 安装

npm install -S yup

修改 BindMailForm.vue

因为我们先前已经把表单处理的逻辑都拆开放到 BindMailForm.vue,所以只要修改这个档案即可。修改重点在送出表单前,先检查邮件地址是否合法。

<script setup>
import {onMounted, ref, defineEmits} from 'vue'
import {sendValidationCodePost} from '/src/service/api'
// import yup
import * as yup from 'yup';

const userName = ref("");
const userToken = ref("");
const userEmail = ref("");
const inputEmail = ref("");

const emit = defineEmits(['nextStep'])

// define mail validate schema
const mailSchema = yup.string().email().required();
const submit = async (mail) => {
  // validate mail before send
  const isMailValid = await mailSchema.isValid(mail);
  if (isMailValid) {
    sendValidationCodePost(userName.value, mail, userToken.value)
        .then((res) => {
          console.log("res: ", res);
          const result = res.data.message;
          emit('nextStep', result);
        })
        .catch((err) => {
          console.log("err: ", err);
        });
  } else {
    alert('请输入有效的信箱地址');
  }
}

onMounted(() => {
  liff.ready.then(() => {
    const user = liff.getDecodedIDToken();
    userName.value = user && user.name;
    userToken.value = user && user.sub;
    userEmail.value = user && user.email;
  })
})
</script>

<template>
  <template v-if="userEmail">
    <p>将发送身份认证码到 {{ userEmail }}</p>
    <button type="button" class="btn" @click="submit(userEmail)">确定</button>
  </template>

  <template v-else>
    <p>发送身份认证码到 <input type="email" v-model="inputEmail" placeholder="请输入 Email"></p>
    <button type="button" class="btn" @click="submit(inputEmail)">确定</button>
  </template>
</template>

一样储存後 npm run build 产生静态档案,并上传到 Github Page,就可以在验证码小帮手检验成果了~


<<:  [Day 16] 第一主餐 pt.8-我带几个data去。你就在此地,不要走动

>>:  Day 27-如何测试 terraform 之二:自动化测试写起来辛苦,但跑起来就是一个爽

G Suite 教育版更名为 Google Workspace for Education,并取消无限制储存空间限制至 100 TB

先前 Google 取消无限制文件云端空间与无限制相簿空间後,大家哀鸿遍野。而原本不受影响的 GSu...

JavaScript Day 5. 型别辨识 typeof

偶尔程序也会碰到需要辨别变数的状态,有时候是用於防止使用者输入奇怪的文字,有时候是帮助自己确认变数的...

Day25-设定大风吹 使用复数values.yaml

在前一章我们学到chart是如何运作的,他能够将values内的值带入deployment.yaml...

Angular 深入浅出三十天:表单与测试 Day08 - 单元测试实作 - 登入系统 by Reactive Forms

今天我们要来为我们用 Reactive Forms 所撰写的登入系统写单元测试,如果还没有相关程序...

Day15 Todo List

import React , { useState }from 'react' const Dol...