如何用String.prototype.startsWith判断链接是否以特定协议开头?
- 内容介绍
- 相关推荐
本文共计889个文字,预计阅读时间需要4分钟。
直接使用 `String.prototype.startsWith` 检查链接,但有时返回 `false`。这通常是因为字符串开头有空格、换行或不可见的 Unicode 字符(如零宽空格 `u200b`)。`startsWith` 是严格匹配,不自动去除前导空格或处理特殊字符。
实操建议:
- 先用
.trim()清除首尾空白:url.trim().startsWith('https://') - 若需兼容带 BOM 的字符串(如 UTF-8 BOM
\ufeff),可加.replace(/^\ufeff/, '') - 避免用正则替代——除非需要更复杂的协议变体(如大小写不敏感),否则纯前缀判断用
startsWith更快、更直观
区分 http 和 https 时要注意大小写和斜杠
startsWith 默认区分大小写,而协议名在 URL 中按规范应为小写,但实际输入可能混入大写(如 HTTP:// 或 Https://)。另外,'http:' 和 'http://' 完全不同——前者匹配 http:foo 这类非法 URL,后者才匹配标准协议+双斜杠结构。
实操建议:
- 明确协议意图:要匹配完整协议+双斜杠,必须用
'https://'或'http://',不能省略// - 如需忽略大小写,先转小写再判断:
url.trim().toLowerCase().startsWith('https://') - 不要写成
url.startsWith('http')——它会把https://和http://都判为 true,失去区分意义
在 Node.js 里处理 file:// 或 chrome-extension:// 协议
前端环境通常不涉及 file:// 或浏览器扩展协议,但在 Electron、Node.js(配合 url 模块)或 Puppeteer 环境中,这些协议很常见。它们长度差异大,且部分协议含冒号但无双斜杠(如 file:),容易误判。
实操建议:
- 匹配
file://时,用url.startsWith('file://');若只写'file:',会错误匹配filename.txt - Chrome 扩展协议形如
chrome-extension://abc123/...,必须写全'chrome-extension://',注意末尾是双斜杠而非单斜杠 - 避免用
indexOf('://') !== -1替代——它无法保证://出现在开头,可能误判https://example.com/path?redirect=https://evil.com
性能与兼容性:IE 不支持 startsWith,但没必要 polyfill
String.prototype.startsWith 在 IE 中完全不可用,但现代项目基本已放弃 IE 支持。若仍需兼容,不要引入整套 polyfill 库——只需一行降级逻辑即可。
实操建议:
- 检查运行环境是否支持:
typeof String.prototype.startsWith === 'function' - 如需兼容 IE,用
str.indexOf('https://') === 0完全等价且无兼容问题 - 别用
substr(0, n) === prefix——当str长度小于n时,substr返回空字符串,导致误判;indexOf则天然安全
真正容易被忽略的是协议后是否紧跟合法字符:比如 'https://' 后必须是域名或 IP,但 startsWith 不验证这点——它只管开头是不是那几个字符。所以判断完协议,还得结合 URL 构造函数做后续校验,否则 'https://.invalid' 也会通过前缀检查。
本文共计889个文字,预计阅读时间需要4分钟。
直接使用 `String.prototype.startsWith` 检查链接,但有时返回 `false`。这通常是因为字符串开头有空格、换行或不可见的 Unicode 字符(如零宽空格 `u200b`)。`startsWith` 是严格匹配,不自动去除前导空格或处理特殊字符。
实操建议:
- 先用
.trim()清除首尾空白:url.trim().startsWith('https://') - 若需兼容带 BOM 的字符串(如 UTF-8 BOM
\ufeff),可加.replace(/^\ufeff/, '') - 避免用正则替代——除非需要更复杂的协议变体(如大小写不敏感),否则纯前缀判断用
startsWith更快、更直观
区分 http 和 https 时要注意大小写和斜杠
startsWith 默认区分大小写,而协议名在 URL 中按规范应为小写,但实际输入可能混入大写(如 HTTP:// 或 Https://)。另外,'http:' 和 'http://' 完全不同——前者匹配 http:foo 这类非法 URL,后者才匹配标准协议+双斜杠结构。
实操建议:
- 明确协议意图:要匹配完整协议+双斜杠,必须用
'https://'或'http://',不能省略// - 如需忽略大小写,先转小写再判断:
url.trim().toLowerCase().startsWith('https://') - 不要写成
url.startsWith('http')——它会把https://和http://都判为 true,失去区分意义
在 Node.js 里处理 file:// 或 chrome-extension:// 协议
前端环境通常不涉及 file:// 或浏览器扩展协议,但在 Electron、Node.js(配合 url 模块)或 Puppeteer 环境中,这些协议很常见。它们长度差异大,且部分协议含冒号但无双斜杠(如 file:),容易误判。
实操建议:
- 匹配
file://时,用url.startsWith('file://');若只写'file:',会错误匹配filename.txt - Chrome 扩展协议形如
chrome-extension://abc123/...,必须写全'chrome-extension://',注意末尾是双斜杠而非单斜杠 - 避免用
indexOf('://') !== -1替代——它无法保证://出现在开头,可能误判https://example.com/path?redirect=https://evil.com
性能与兼容性:IE 不支持 startsWith,但没必要 polyfill
String.prototype.startsWith 在 IE 中完全不可用,但现代项目基本已放弃 IE 支持。若仍需兼容,不要引入整套 polyfill 库——只需一行降级逻辑即可。
实操建议:
- 检查运行环境是否支持:
typeof String.prototype.startsWith === 'function' - 如需兼容 IE,用
str.indexOf('https://') === 0完全等价且无兼容问题 - 别用
substr(0, n) === prefix——当str长度小于n时,substr返回空字符串,导致误判;indexOf则天然安全
真正容易被忽略的是协议后是否紧跟合法字符:比如 'https://' 后必须是域名或 IP,但 startsWith 不验证这点——它只管开头是不是那几个字符。所以判断完协议,还得结合 URL 构造函数做后续校验,否则 'https://.invalid' 也会通过前缀检查。

