html5 input[type="url"]仅校验协议头格式(protocol://),不验证协议真实性或安全性;需结合url.canparse()或try-catch new url()及白名单过滤增强校验。

HTML5 中用 input[type="url"] 可以触发浏览器对协议头的最基本检查,但它只认“有协议+斜杠”结构,不验证协议是否真实存在或是否被允许。比如 http://a、https:///example.com 都会被认为合法,而 www.example.com 或 example.com/path 则直接报错——因为缺协议头。
type="url" 的协议头校验逻辑
浏览器会强制要求输入值必须以 protocol:// 形式开头(支持 http、https、ftp、file、data 等 RFC 标准协议),且协议后紧接 //。它不关心协议是否常用,也不拦截 javascript: 或 vbscript: 这类危险协议。
- ✅ 通过:
https://example.com、ftp://files.org、file:///home/doc.txt - ❌ 拒绝:
example.com(无协议)、http:/example.com(少一个斜杠)、http//example.com(缺冒号)
不能只靠 type="url" 的原因
这个原生校验太宽松:它不识别自定义协议(如 myapp://home),也不阻止明显无效组合(如 htp://a)。更重要的是,它对用户粘贴的内容几乎不处理——带空格、换行、中文字符的 URL 仍可能通过初始校验。
- 用户粘贴
https://example.com(首尾空格)→ 原生校验可能放行 - 用户输入
http://中文.com→ 浏览器自动转义为http://xn--fiq228c.com,但部分旧版不兼容 - 提交时若未触发校验(如用 JS 调用
form.submit()而非点击按钮),校验可能被跳过
增强协议头检查的实用做法
在保留原生语义的同时,加一层轻量 JS 补位,重点盯协议头是否真实可解析:
- 监听
input或blur事件,对值做.trim() - 用
URL.canParse(url)快速判断(现代浏览器支持):
URL.canParse("https://a") → true;URL.canParse("www.a") → false - 不支持
canParse时降级为try { new URL(url); } catch(e) { … } - 业务中需禁用特定协议(如
javascript:),得额外白名单过滤,不能依赖原生
表单提交前的兜底建议
即使用了 type="url" 和 required,也应在 JS 提交逻辑里再校验一次:
- 调用
input.checkValidity()主动触发原生校验 - 若失败,用
input.reportValidity()强制显示提示 - 避免直接取
input.value发送,先确保input.validity.valid === true











