是的,使用 url() 非常严格地验证网站

Yup validation of website using url() very strict

我正在尝试使用

将输入字段验证为网站
yup.string().url()

但似乎如果不发送协议就会出错,而网站应该灵活地接受例如 whosebug.com

请帮忙

您可以使用自己的 regex,而不是使用默认的 url 验证器。您的代码更改如下:

website: Yup.string()
        .matches(
            /((https?):\/\/)?(www.)?[a-z0-9]+(\.[a-z]{2,}){1,3}(#?\/?[a-zA-Z0-9#]+)*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/,
            'Enter correct url!'
        )
        .required('Please enter website'),

您可以对 regex 使用自己的规则并验证 url。您可以阅读更多相关信息 there

在这里试一试:https://regex101.com/r/O47zyn/4

刚刚完成@aturan23,你可以在[a-z0-9][a-zA-Z0-9#]里面加一个-,像这样:

((https?):\/\/)?(www.)?[a-z0-9-]+(\.[a-z]{2,}){1,3}(#?\/?[a-zA-Z0-9#-]+)*\/?(\?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$

您可以这样验证 url:

  • material-ui.com

  • https://github.com/mui-org/material-ui

  • http://github.com/mui-org/material-ui

  • github.com/mui-org/material-ui/core#teste

很多 urls 都在经过验证的答案上中断。更接近 Yup.url() 但允许省略 http、www。和//将是:

const URL = /^((https?|ftp):\/\/)?(www.)?(((([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

Yup.string().matches(URL, 'Enter a valid url')

所有答案都将 www.mywebsite 视为有效。事实并非如此。

const re = /^((ftp|http|https):\/\/)?(www.)?(?!.*(ftp|http|https|www.))[a-zA-Z0-9_-]+(\.[a-zA-Z]+)+((\/)[\w#]+)*(\/\w+\?[a-zA-Z0-9_]+=\w+(&[a-zA-Z0-9_]+=\w+)*)?$/gm

Yup.string().matches(re,'URL is not valid')

匹配项:

  • vercel.com
  • www.vercel.com
  • uptime-monitor-fe.vercel.app
  • https://uptime-monitor-fe.vercel.app/

向@trash_dev 的正则表达式添加更多验证,

你可以试试https://regex101.com/r/V5Y7rn/1/

const regMatch = /^((http|https):\/\/)?(www.)?(?!.*(http|https|www.))[a-zA-Z0-9_-]+(\.[a-zA-Z]+)+(\/)?.([\w\?[a-zA-Z-_%\/@?]+)*([^\/\w\?[a-zA-Z0-9_-]+=\w+(&[a-zA-Z0-9_]+=\w+)*)?$/;

Yup
 .string()
 .matches(regMatch, "Website should be a valid URL")

它还考虑了 URL 的额外注意事项,例如:

www.test-my-skills.gov.cz/0999asd-xzc88?0-_/sad%20123/@asdas
asdasd.com/asdasd/asdasd/asdasd/@asasd
https://www.somehow.com/@aasd
https://www.test.facebook.com/@sdas
http://www.computer.com.au/
const isValidUrl = (url) => {
    try {
        new URL(url);
    } catch (e) {
        return false;
    }
    return true;
};

const FormSchema = Yup.object({
    url: Yup.string().test('is-url-valid', 'URL is not valid', (value) => isValidUrl(value)),
});

https://dev.to/calvinpak/simple-url-validation-with-javascript-4oj5

我正在编辑@Animesh Singh 的正则表达式以添加更多验证。

首先你需要考虑为什么要验证这个,你会把它存储在某个地方吗?你想避免什么?根据您的回答,您可以向正则表达式添加一些自定义验证。

我搜了一下,其实url的长度和域中的点数是有限制的。域名也可以有连字符。

https://news.gandi.net/en/2020/08/should-i-put-a-dash-in-my-domain-name/#:~:text=The%20hyphen%2C%20commonly%20known%20as,with%20no%20space%20between%20them.

What is the maximum length of a URL in different browsers?

引用 wikipedia :

The hierarchy of domains descends from the right to the left label in the name; each label to the left specifies a subdivision, or subdomain of the domain to the right. For example: the label example specifies a node example.com as a subdomain of the com domain, and www is a label to create www.example.com, a subdomain of example.com. Each label may contain from 1 to 63 octets. The empty label is reserved for the root node and when fully qualified is expressed as the empty label terminated by a dot. The full domain name may not exceed a total length of 253 ASCII characters in its textual representation.[9] Thus, when using a single character per label, the limit is 127 levels: 127 characters plus 126 dots have a total length of 253. In practice, some domain registries may have shorter limits.

所以我将长度限制设置为 2048 个字符,并限制域最多有 126 个单点接 63 个字符。我看不出有什么方法可以在不拆分 URL 的情况下检查 253 个字符的域限制。我这里也不检查连字符。

所以我通过将 + 切换为 {1,5}

来限制 url 可以拥有多少 (\.[a-zA-Z]{1,63})
const regex = /^(?=.{4,2048}$)((http|https):\/\/)?(www.)?(?!.*(http|https|www.))[a-zA-Z0-9_-]{1,63}(\.[a-zA-Z]{1,63}){1,5}(\/)?.([\w\?[a-zA-Z-_%\/@?]+)*([^\/\w\?[a-zA-Z0-9_-]+=\w+(&[a-zA-Z0-9_]+=\w+)*)?$/;

Yup
 .string()
 .matches(regMatch, "Website should be a valid URL")

在我的用例中,我不想要主域,所以我总是需要通过将 (\/)? 切换为 (\/){1}

来在斜线后添加一些内容
const regex = /^(?=.{4,2048}$)((http|https):\/\/)?(www.)?(?!.*(http|https|www.))[a-zA-Z0-9_-]{1,63}(\.[a-zA-Z]{1,63}){1,5}(\/){1}.([\w\?[a-zA-Z-_%\/@?]+)*([^\/\w\?[a-zA-Z0-9_-]+=\w+(&[a-zA-Z0-9_]+=\w+)*)?$/;

Yup
 .string()
 .matches(regMatch, "Website should be a valid URL")

我请大家测试这个正则表达式,如果有任何意外行为,请告诉我。