I recently had a chance to pair program with a friend who was just breaking into Front-End web development. Considering him, myself, and others I’ve had the chance to work with over time, I’d say it’s a lot more easier to resolve to use a validation library, especially for someone who’s just getting acquainted with developing applications.
我最近有机会与一个刚进入前端Web开发的朋友配对程序。 考虑到他,我本人以及随着时间的推移我有机会与之合作的其他人,我想说,使用验证库解决起来要容易得多,特别是对于刚开始开发应用程序的人而言。
Input validation is a paramount control for testing inputs provided by both users and other applications, usually before the inputs enter the workflow of our app. We do this to protect intermediate resources — DBs, data, APIs, networking/computing power, e.t.c.
输入验证是测试用户和其他应用程序提供的输入的首要控制,通常在输入进入我们应用程序的工作流之前。 我们这样做是为了保护中间资源-数据库,数据,API,网络/计算能力等
我为什么要进行自定义验证?(Why should I go for Custom Validation?)
Validation libraries are shipped with a range of precompiled validators that we can directly access from within our apps. Sounds super easy, right? It is. Why then should we have to write custom procedures while we can have a lib do the work for us? Well, here are the three basic things that come to mind:
验证库附带了一系列预编译的验证器,我们可以从我们的应用程序内直接访问它们。 听起来超级容易,对吧? 它是。 那为什么我们必须要编写一个自定义过程,而我们可以让一个lib为我们做这些工作呢? 好吧,这是我想到的三个基本要素:
1.特定于数据的测试。 (1. Data-Specific tests.)
A developer writing a generic validation library will work with the presumption that the validators shipping with the lib should suit a wide range of inputs. The preciseness of any given test in the lib is therefore not guaranteed. For instance, suppose we are validating a users Name. We can use a readily available text-only function from a given lib, but what if we want to additionally allow users to use periods (for initials) or apostrophes in the provided name?
编写通用验证库的开发人员将假定lib附带的验证器应适合各种输入。 因此,不能保证lib中任何给定测试的准确性。 例如,假设我们正在验证用户名。 我们可以使用给定库中的随时可用的纯文本功能,但是如果我们想另外允许用户在提供的名称中使用句点(用于缩写)或撇号怎么办?
Being able to write your own tests helps you fine-tune them to suit your specific data.
能够编写自己的测试有助于您微调它们以适合您的特定数据。
2.性能。 (2. Performance.)
Like any Commercial-Off-The-Shelf software, validation libs include features that we might end up not using. Consider the dateISO or url tests you and additional helper functions that ship with a validation lib that you won’t have to use at all. Why use 5/12 tests in a 340kb lib while you can write a custom 890 bytes custom solution? Generally, the bigger the file sizes are on your app, the longer the app takes to load.
像任何现成的商业软件一样,验证库包含一些我们可能最终不使用的功能。 考虑一下您使用的dateISO或url测试,以及完全不需要使用的验证库附带的其他辅助函数。 为什么可以在340kb的库中使用5/12测试,同时又可以编写890字节的自定义解决方案? 通常,应用程序上的文件大小越大,应用程序加载所需的时间就越长。
3. Visibility.
3.能见度。
There’s no such thing as an opaque library, but, when making use of a minified lib file (recommended), you might as well be working with one. Understanding every column of every line of code in your app gives you the confidence to move things around as you’d like to, while deciding on the most optimum approach. A custom procedure will help you achieve this.
没有不透明的库,但是,当使用缩小的lib文件(推荐)时,最好也使用它。 了解应用程序中每一行代码的每一列,可以使您信心十足地随心所欲地移动事物,同时决定采用最佳方法。 定制过程将帮助您实现这一目标。
只需三个简单步骤即可进行验证 (Validation in three easy steps)
We can narrow the process down into three simple steps — obtaining input values, testing these values and, providing processing results.
我们可以将过程缩小为三个简单的步骤-获取输入值,测试这些值以及提供处理结果。
1.获取输入值。 (1. Fetching input values.)
JavaScript natively provides document methods that help with DOM interactions. The approach to get an input value will vary with different JS frameworks. Inputs are almost always associated with an <input> tag, but, this will not always be the case. It’s advisable to assign unique identifiers to your markup elements — id, class — for easier retrieval while working on the app’s behavior.
JavaScript本身提供了有助于DOM交互的文档方法。 获取输入值的方法会因不同的JS框架而异。 输入几乎总是与<input>标记相关联,但是,并非总是如此。 建议为标记元素(id,class)分配唯一的标识符,以便在处理应用行为时更容易检索。
Note: If you’re working with a JS framework, please refer to the respective documentation on how to access input values.
注意:如果您使用的是JS框架,请参阅有关如何访问输入值的相应文档。
Accessing input values now becomes as easy as:
现在,访问输入值变得很容易:
let
inputVal = document.getElementById('id').value,
inputValII = document.getElementByClassName('class').value;/* Where 'id', 'class' represent the input element's id/class respectively */
2. Testing Input Values.
2.测试输入值。
Regexs — Regular Expressions — are a conceptual search pattern for processing strings. We can use the String.prototype methods search and match, or the RegExp.prototype method test to check whether a string matches a defined regexp pattern. I’m going to stick to the RegExp.prototype.test() method.
Regexs -正则表达式-用于处理字符串的概念搜索模式。 我们可以使用String.prototype方法search和match ,或者使用RegExp.prototype方法test来检查字符串是否与定义的regexp模式匹配。 我将坚持使用RegExp.prototype.test()方法。
If we have a String stored in a variable str and a RegExp rg, the test method can then be applied as:
如果我们有一个存储在变量str中的String和一个RegExp rg ,则可以将测试方法应用为:
rg.test(str);
The test method returns true if the String str matches the RegExp pattern rg, and otherwise returns false. With that in mind, here’s a RegExps cheat sheet for the various inputs we’d have to handle in an app:
如果String str与RegExp模式rg相匹配,则测试方法返回true ,否则返回false。 考虑到这一点,这是我们需要在应用程序中处理的各种输入的RegExps备忘单:
Comparison and Relational operators come in handy in comparing values:
比较和关系运算符在比较值时派上用场:
let min = (value, param) => {
return value >= param;
}, max = (value, param) => {
return value <= param;
}, equalTo = (value, param) => {
return value === param;
};
3.提供处理结果。 (3. Providing processing results.)
Feedback is one of the key guidelines of good UI design — it gives the user an immediate feedback of the result of an action. Given that we’d be handling varying user inputs at any given moment, it’s best to create a messages object containing response messages for invalid inputs. Based on the result of the processing step discussed in 2. above, we can then refer to this object to update the UI accordingly. The following code snippet demonstrates how to ideally go about it:
反馈是良好的UI设计的关键准则之一-它为用户提供了操作结果的即时反馈。 鉴于我们将在任何给定时刻处理各种用户输入,因此最好创建一个包含无效输入响应消息的message对象。 基于上面2中讨论的处理步骤的结果,然后我们可以引用该对象来相应地更新UI。 下面的代码片段演示了如何理想地实现它:
let
url = /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/, $ = (e) => {
return document.getElementByClassName(e);
},
validURL = (value) => {
return url.test(value);
}, messages = {
url: 'Please provide a valid email address',
dateISO: 'Please provide a valid date (ISO)',
number: 'Please provide a valid number',
digits: 'Please enter only digits',
text: 'Please enter only text'
};if(!validURL($('url').value) {
$('tests-log').textContent(messages.url);
}/*Where
'url' = input element where user provides a URL,
'tests-log' = a blank paragraph reserved on the form for providing feedback.
*/
包装全部 (Wrapping it all up)
A successful verification process implies a green light to proceed to the next step in the app’s workflow — this will vary depending on your system’s design. While we strive to write validation for an app to ensure that everything is 100% perfect, there will always be an edge case where bad data could get submitted. The reason we validate is to encourage proper data submission and prevent mistakes.
成功的验证过程意味着可以继续进行应用工作流程的下一步-这将取决于您系统的设计。 尽管我们努力为应用程序编写验证以确保所有内容都100%完美,但总会出现极端情况,可能会提交错误的数据。 我们验证的原因是鼓励适当的数据提交并防止错误。