5

情况如下:我有一个很棒的大文本输入框用于 URL:https ://asafaweb.com

不过,这不需要遵守 URL 的严格定义;我允许没有方案的地址,然后出于可用性目的默认使用 HTTP。例如,“stackoverflow.com”将被视为有效 URL。但也有一些 URL 由于各种原因我不想允许(即它们已被列入黑名单或它们是内部 IP 地址范围)。

我想将输入的类型设置为“url”而不是默认的“文本”,以便移动设备上的用户获得专为 URL 上下文设计的键盘(即 iOS 为您提供“.com”按钮),问题是一旦我这样做,与 ASP.NET MVC 捆绑的默认不显眼的 jQuery 验证需要一个带有方案的 URL,从而破坏了我的无方案 URL 支持。

这是一个 MVC4 站点,我有一个 HTML 助手,如下所示:

@Html.TextBoxFor(m => m.ScanUrl, new { type = "url" })

然后,ScanUrl 属性有一个自定义 ValidationAttribute,它会执行所有定制检查以确保可以扫描 URL。

如何在没有 jQuery 验证插入和想要确保 URL 是严格的URL 的情况下保持现有的验证模式?

4

3 回答 3

8

如果您不需要在此站点的任何地方进行严格的 URL 验证,那么修改 jQuery Validation 验证 URL 的方式可能是处理该问题的最简单方法。如果您使用的是 MVC 4 附带的版本,您会在 jquery.validate.js 的第 1034 行找到它。

您可以在插件脚本中调整正则表达式,或者您可以在加载 jQuery Validation 后修补 url 验证方法:

<script src="/Scripts/jquery.validate.js"></script>
<script>
  // To no-op url validation completely.
  jQuery.validator.methods.url = function(value, element) {
    return this.optional(element) || true;
  };

  // Or, continue validating everything else as previously, 
  //  but not require the protocol (double check my change to the regex...).
  jQuery.validator.methods.url = function(value, element) {
    return this.optional(element) || /^(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
  };    
</script>

之后对其进行修补的主要优点是您不会被绑定到脚本的调整版本,并且可以在以后更新 jQuery Validation 本身而不会丢失您自定义的 url 验证器。这对您来说可能很明显,但可能有助于其他人稍后找到此答案。

于 2012-09-03T01:26:07.223 回答
0

如果焦点不在/更改上,您可以使用 javascript 自动将架构添加到输入中的 URL。

于 2012-09-01T03:00:05.477 回答
0

您还可以告诉 jQuery Validation 插件根据您指定的选择器选择性地忽略输入字段,该选择器可以是您添加到所有要忽略的元素的类,例如class="ignorejQueryValidate",或者在您的情况下,所有带有type="url".

请参阅jQuery 文档中有关验证插件方法的ignore选项部分。validate()

@using (Html.BeginForm("SomeAction", "SomeController", FormMethod.Post, new { id = "myForm"}))
{
    @Html.TextBoxFor(m => m.ScanUrl, new { type = "url", @class = "ignorejQueryValidate" })
}

$("#myForm").validate({
    ignore: ".ignorejQueryValidate"
});

或者

@using (Html.BeginForm("SomeAction", "SomeController", FormMethod.Post, new { id = "myForm" }))
{
    @Html.TextBoxFor(m => m.ScanUrl, new { type = "url" })
}

$("#myForm").validate({
    ignore: "input[type=url]"
});
于 2012-09-04T01:48:56.093 回答