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

时间:2017-10-17 08:24:30

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

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

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

修改 我将添加一些更具体的问题,但请不要限制您对这些的回答。

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

我希望自己清楚明白。如果没有,请告诉我,以便我可以尝试更具体。

2 个答案:

答案 0 :(得分:3)

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

对于服务器端验证期间的HTTP状态代码,在不同的方案中您应该响应的状态代码没有设置标准。如果您是唯一使用API​​的人,那么您可以随心所欲地做任何事情。

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

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

此时以1和3开头的代码对我们来说并不感兴趣。事实上,我们唯一关注的代码是已加星标的代码:

  • 200 OK
  • 201创建
  • 204 No Content
  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 409冲突
  • 500内部服务器错误

以下是一些经常使用这些规则的经验法则:

当事情顺利的时候

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

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

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

每当你删除,修补或投入某些东西时,你可以使用 204 No Content 。您永远不会提供包含此状态代码的消息。

当事情不顺利时

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

400 Bad Request 用于未通过验证的请求,缺少字段的请求等。发送的消息取决于您,但它通常包含在消息字段中,如下所示:

response.status = HttpStatus.BAD_REQUEST;
response.message = { 'message': 'Illegal schoolID' };
res.status(response.status).json(response.message);

这是我用于提供非法schoolID的GET请求的消息。如果你想在客户端验证错误信息,你当然可以提供实际的验证结果对象。

401 Unauthorized 403 Forbidden 用于身份验证(登录等)。

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

当输入语法正确但语义错误时,

422 Unprocessable Entity 也可用于验证错误。

发生实际错误时

如果引发错误或您在回调中出错,则可以使用 500内部服务器错误。例如

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在视图中绑定并显示给用户。

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

更具体地回答问题1

我认为设计它的好方法是假装你只编写服务器端代码和API。假装其他人正在做前端,然后想象他们想要看到什么。或者假设您的API完全公开,并且每个人都可以使用它。如果你这样做并且没有假设客户端是什么或者是谁,那么后端将从前端松散耦合,这就是你想要的。

你唯一可以假设的是,有人会试图用一个名为Postman的应用程序破坏你的一天。

答案 1 :(得分:0)

@Taimoor,您可以查看希望它有用的链接:HTTP Status Codes