查看源码 其内部使用了一个库
const parse = require('parseurl');
parseurl的源码
function parseurl (req) {
var url = req.url
// -->先判断是不是undefined
if (url === undefined) {
// URL is undefined
return undefined
}
// 判断这个url是不是被解析过了
var parsed = req._parsedUrl
if (fresh(url, parsed)) {
// Return cached URL parse
return parsed
}
// Parse the URL 解析url
parsed = fastparse(url)
parsed._raw = url
return (req._parsedUrl = parsed)
};
fastparse的代码
看fastparse的代码之前先看下parse (新版的node不使用这种用法)
var url = require('url');
var parse = url.parse;
let a = 'https://user:pass@sub.host.com:8080/p/a/t/h?query=string#hash';
console.log(parse(a))
//Url 这个函数解析之后得到的内容
{
protocol: 'https:',
slashes: true,
auth: 'user:pass',
host: 'sub.host.com:8080',
port: '8080',
hostname: 'sub.host.com',
hash: '#hash',
search: '?query=string',
query: 'query=string',
pathname: '/p/a/t/h',
path: '/p/a/t/h?query=string',
href: 'https://user:pass@sub.host.com:8080/p/a/t/h?query=string#hash'
}
function fastparse (str) {
//如果不是个字符串或者不是/开头 直接使用parse(str)
if (typeof str !== 'string' || str.charCodeAt(0) !== 0x2f /* / */) {
return parse(str)
}
var pathname = str
var query = null
var search = null
// This takes the regexp from https://github.com/joyent/node/pull/7878
// Which is /^(\/[^?#\s]*)(\?[^#\s]*)?$/
// And unrolls it into a for loop
//遍历每一个字符
for (var i = 1; i < str.length; i++) {
switch (str.charCodeAt(i)) {
case 0x3f: /* ? */
if (search === null) { //只处理一次
pathname = str.substring(0, i)
query = str.substring(i + 1)
search = str.substring(i)
}
break
//下面这些直接返回parse(str)
case 0x09: /* \t */
case 0x0a: /* \n */
case 0x0c: /* \f */
case 0x0d: /* \r */
case 0x20: /* */
case 0x23: /* # */
case 0xa0:
case 0xfeff:
return parse(str)
}
}
//如果没有上述情况的发生 就把解析到的内容赋值到Url类中
var url = Url !== undefined
? new Url()
: {}
url.path = str
url.href = str
url.pathname = pathname
if (search !== null) {
url.query = query
url.search = search
}
return url
}