forms - 如何在服务器端响应不同的验证错误?

标签 forms validation error-handling server-side http-status-codes

我是第一次开发网站,所以选择使用mongodb,node,express和angular,即MEAN Stack。我正在使用的前几个功能之一是简单的表单,当前手头的任务是表单验证。我已经进行了大量关于如何验证表单提交的研究,并且了解必须同时实现客户端验证和服务器端验证。客户端验证可提供更好的用户体验,而服务器端验证则出于各种原因,但主要出于安全性考虑。

但是,我面临的问题是有关如何将表单数据提交到我的REST API时可能出现的不同错误。我想知道可能出现的每种情况,以及如何处理每种情况,例如响应哪种状态代码,我应该提供特定的错误消息吗?

编辑:
我将添加一些更具体的问题,但请不要将您的回答仅限于这些

1)我可以假定没有客户要求的字段的请求实际上不是来自我的客户的,并且可能是一个对手,所以我应该发送“错误请求(400)”而不提供任何错误消息吗?
2)我是否应该甚至将200状态以外的其他状态代码用于验证错误,例如缺少必填字段或格式错误的字段?我之所以这样问是因为,当我发送4XX响应时,在浏览器的控制台中会生成一个错误,当网站运行正常时,这似乎并不正确。

我希望我能使自己清楚。如果没有,请让我知道,以便我可以更加具体。

最佳答案

当您声明同时需要客户端验证和服务器端验证时,您是正确的。您要如何呈现客户端验证错误完全取决于您。通常禁用提交按钮,使无效输入框的边框变为红色等。 HTML5已经为某些事物(数字,日期,长度)内置了验证方法。如果这还不够,您可以在Google上查找 Angular 形式验证。

至于服务器端验证期间的HTTP状态代码,在不同情况下应以何种状态代码响应没有设置标准。如果您是唯一使用API​​的人,那么您就可以自由地做任何您想做的事情。

但是,如果您想遵循API的REST原则,则存在事实上的标准。如果我们查看Lequoa提供的link,则会发现以下类别:

  • 1xx信息
  • 2xx成功
  • 3xx重定向
  • 4xx客户端错误
  • 5xx服务器错误

  • 以1和3开头的代码目前对我们来说并不有趣。实际上,我们唯一关心的代码是加星号的代码:
  • 200 OK
  • 201创建了
  • 204没有内容
  • 400错误的请求
  • 401未经授权的
  • 403禁止使用
  • 404未找到
  • 409冲突
  • 500内部服务器错误

  • 以下是通常使用这些方法的一些经验法则:

    当一切顺利时

    200范围内的状态码用于成功请求。

    服务器在GET后成功返回资源后,请使用200 OK。该消息是请求的内容。

    服务器在POST之后成功创建资源后,可以使用201 CREATED。该消息通常是创建的内容(例如,新的博客文章)。

    每当您删除,修补或放置某些内容时,都可以使用204 No Content。您永远不会提供带有此状态代码的消息。

    当事情不顺利时

    当客户端发送错误请求时,将使用400范围。

    400错误的请求用于未通过验证的请求,缺少字段的请求等。发送的消息由您决定,但通常包裹在消息字段中,如下所示:
    response.status = HttpStatus.BAD_REQUEST;
    response.message = { 'message': 'Illegal schoolID' };
    res.status(response.status).json(response.message);
    

    这是我将用于提供非法SchoolID的GET请求的消息。如果要在客户端美化错误消息,您当然可以提供实际的验证结果对象。

    401未经授权和403禁止用于身份验证(登录等)。

    客户端为不存在的资源发送GET时使用404 Not Found。

    当输入在语法上正确但在语义上是错误的时,422不可处理实体也可以用于验证错误。

    当发生实际错误时

    如果引发错误或在回调中收到错误,则可以使用500 Internal Server Error。例如
    Model
      .findById(modelId)
      .exec(function (err, models) {
          if (err) {
             res.status(500).json(err);
             return;
          }
          ...
    

    这不是用于验证错误,而是用于永远不会发生的错误。验证错误毕竟并不少见。内部服务器错误是您的服务器端代码中的错误,或者是服务器着火或类似情况。

    处理客户端代码中的错误

    当浏览器返回4 **或5 **状态代码时,它必须进行处理。它们将被打印到控制台,这很好,您不应使用2 **代码使其消失。浏览器必须阅读错误消息,并以用户友好的方式将其显示给用户。如果服务器响应随附的消息是用户友好的,则可以直接显示该消息,否则,您必须编写如下代码(AngularJS):
    schoolDataFactory.patchUpdateSchool(vm.school._id, newSchoolData).then(function (res) {
      if (res.status === 204) {
        vm.errorMessage = ''
        vm.message = 'School info was updated.'
      } else {
        console.log('The server should send 204 No Content on successful PATCH, so this shouldn't happen.')
      }
    }).catch(function (error) {
    
      vm.message = ''
    
      if (error.status === 400 && error.data.message === 'ValidationError: schoolName') {
        vm.errorMessage = 'Fix the school name'
      } else if (error.status === 400 && error.data.message === 'ValidationError: schoolAddress') {
        vm.errorMessage = 'Fix the school address'
      } else if (error.status === 500) {
        vm.errorMessage = 'Something is wrong with the server.'
      }
    })
    

    该假设示例将带有新学校数据的PATCH请求发送到服务器。如果PATCH成功,则浏览器将接收状态代码204,并在then()中运行回调。如果收到4 **或5 **,它将在catch()中运行回调,以处理错误。 vm.errorMessage和vm.message绑定(bind)在 View 中并显示给用户。

    关键是,如果服务器的响应很丑陋,则可能必须在客户端代码中转换响应消息。

    更具体地讲问题1

    我认为设计它的一种好方法是假装您仅在编写服务器端代码和API。假装有人在做前端,然后想象他们想看到什么。或者想象您的API是完全公开的,并且每个人都可以使用它。如果以这种方式进行操作,并且不假设客户端是什么或谁,则后端将与前端松散耦合,这就是您想要的。

    您可以假设的唯一事情是,有人将尝试使用名为Postman的应用程序破坏您的一天。

    关于forms - 如何在服务器端响应不同的验证错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46785679/

    相关文章:

    java - 如何编写 Java 代码以确保字符串长度恰好为 5 位

    css - 如何减少梯度误差?

    C# MVC - 根据模型动态获取属性名称

    c++ - 为模板类中的无效数据类型生成编译时错误?

    wcf - silverlight wcf 回调错误 try catch 失败

    php - jQuery 动态添加的表单字段不会提交

    javascript - 使用经典的 asp 或 javascript(且兼容 IE)上传 imgur?

    javascript - 如何在发布 html 表单时进行 Base64 编码?

    css - HTML5 表单选择字段直到悬停才显示

    java - Java libGdx : FreeTypeFontGenerator is not working (Black screen)