【问题标题】:Using Yup to validate credit card details使用 Yup 验证信用卡详细信息
【发布时间】:2018-11-18 09:38:46
【问题描述】:

我正在使用 Yup 验证注册表单,但由于需要 Yup 的 stringnumber 架构中的方法,我正在努力验证信用卡字段。

例如卡号不应超过 16 个字符。使用string 模式中的max 方法可以轻松实现这一点。但是,如果用户输入 16 个字母而不是数字,则当前将通过验证。如果我将架构从string 更改为number,则max 的行为方式不同,而是将字段中的所有数字相加并检查它是否等于小于最大数字。

我需要使用 number 架构的 minmax 方法的字段示例是到期月份,其中最小值为 1,最大值为 12。但是,我仍然需要检查以确保该字段中的字符数为 2,因为前导 0 应用于 1 月至 9 月。

const validationSchema = {
  cardNumber: Yup.string()
    .label('Card number')
    .max(16)
    .required(),
  cvc: Yup.string()
    .label('CVC')
    .min(3)
    .max(4)
    .required(),
  nameOnCard: Yup.string()
    .label('Name on card')
    .required(),
  expiryMonth: Yup.string()
    .label('Expiry month')
    .min(2)
    .max(2)
    .required(),
  expiryYear: Yup.string()
    .label('Expiry year')
    .min(4)
    .max(4)
    .required(),
};

【问题讨论】:

    标签: javascript yup


    【解决方案1】:

    您可以使用 Yup 的测试方法并返回第三方验证器给出的truefalse,而不是像这样进行验证。例如:braintree/card-validator。 所以,它看起来像这样:

    import valid from 'card-validator'; //import statement
    
    CreditCardNumber: 
    Yup
        .string()
        .test('test-number', // this is used internally by yup
        'Credit Card number is invalid', //validation message
         value => valid.number(value).isValid) // return true false based on validation
        .required()
    

    还有valid.expirationDate(value).isValidvalid.cvv(value).isValidvalid.postalCode(value).isValid

    https://github.com/braintree/card-validator

    https://github.com/jquense/yup#mixedtestname-string-message-string--function-test-function-schema

    希望对你有帮助!

    【讨论】:

      【解决方案2】:

      这是我过去使用Yup's .test() 方法验证信用卡过期的方法。

      1) 我必须使用掩码,通过使用掩码,我必须使用的 DOM 元素是单个输入字段。掩码看起来像这样__/__(两个下划线由正斜杠分隔)

      起初,验证是这样开始的:

      export const expirationDate = Yup.string()
        .typeError('Not a valid expiration date. Example: MM/YY')
        .max(5, 'Not a valid expiration date. Example: MM/YY')
        .matches(
          /([0-9]{2})\/([0-9]{2})/,
          'Not a valid expiration date. Example: MM/YY'
        )
        .required('Expiration date is required')
      

      即使有服务器端验证,我仍然应该努力防止错误输入,例如:13/1999/99。为什么要浪费往返网络通话。所以,在.matches().required() 方法调用之间我添加了:

      .test(
          'test-credit-card-expiration-date',
          'Invalid Expiration Date has past',
          expirationDate => {
            if (!expirationDate) {
              return false
            }
      
            const today = new Date()
            const monthToday = today.getMonth() + 1
            const yearToday = today
              .getFullYear()
              .toString()
              .substr(-2)
      
            const [expMonth, expYear] = expirationDate.split('/')
      
            if (Number(expYear) < Number(yearToday)) {
              return false
            } else if (
              Number(expMonth) < monthToday &&
              Number(expYear) <= Number(yearToday)
            ) {
              return false
            }
      
            return true
          }
        )
        .test(
          'test-credit-card-expiration-date',
          'Invalid Expiration Month',
          expirationDate => {
            if (!expirationDate) {
              return false
            }
            const today = new Date()
              .getFullYear()
              .toString()
              .substr(-2)
      
            const [expMonth] = expirationDate.split('/')
      
            if (Number(expMonth) > 12) {
              return false
            }
      
            return true
          }
        )
      

      参考:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-24
        • 2014-02-05
        • 1970-01-01
        • 2011-06-02
        • 1970-01-01
        • 1970-01-01
        • 2012-10-12
        • 1970-01-01
        相关资源
        最近更新 更多