08-网络地址解析-url

223 阅读3分钟

网络地址解析-url

nodejs中,提供了 url 这个非常实用的模块,用来做url的解析,在做node服务端的开发的时候经常用到,实用很简单,总共分为三个方法

模块方法概述

url模块有三个方法, 分别是;
url.parse(urlString); // 将url字符串解析为object,便于开发着进行操作
url.format(ulrObj); // 是parse的反向操作
url.resolve(from, to); // 以from作为起始地址,解析出完整的目标地址

url.parse

完整语法: url.parse(urlString,parseQueryString,slashesDenoteHost)
1.parseQueryString: 默认为false,如果为false,则 urlObject.query 为未解析的字符串,比如 nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1 ,且对应的值不会decode,如果 parseQueryString为true,则 urlObject.query 为object,比如 {aaa:123},且值会被decode
2.slashesDenoteHost 默认为false,如果为true,那么类似 /foo/bar 里面的foo就会被认为是 hostname 如果为false, 则foo被认为是 pathname 的一部分
3.关于解析得到的 urlObject 会在下一个小节进行详细介绍

例子:1.参数值不进行解析

const str =
  "http://Chyingp:HelloWorld@ke.qq.com:8080/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1#part=1";
const obj = url.parse(str);
console.log(obj);
// Url {
//   protocol: 'http:',
//   slashes: true,
//   auth: 'Chyingp:HelloWorld',
//   host: 'ke.qq.com:8080',
//   port: '8080',
//   hostname: 'ke.qq.com',
//   hash: '#part=1',
//   search: '?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
//   query: 'nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
//   pathname: '/index.html',
//   path: '/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
//   href: 'http://Chyingp:HelloWorld@ke.qq.com:8080/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1#part=1'
// }

例子 2:对参数进行 decode

  const str = "http://Chyingp:HelloWorld@ke.qq.com:8080/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1#part=1"
  const obj = url.parse(str, true)
  console.log(obj);
// Url {
//   protocol: 'http:',
//   slashes: true,
//   auth: 'Chyingp:HelloWorld',
//   host: 'ke.qq.com:8080',
//   port: '8080',
//   hostname: 'ke.qq.com',
//   hash: '#part=1',
//   search: '?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
//   query: [Object: null prototype] { nick: '程序猿小卡' },
//   pathname: '/index.html',
//   path: '/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
//   href: 'http://Chyingp:HelloWorld@ke.qq.com:8080/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1#part=1'
// }

  输出结果发现, query 被解析成了object, 并且进行了decode

例子 3:针对路径 //foo/bar 的处理

  const str = '//foo/bar'
  const obj = url.parse(str, true, false)
  console.log(obj);
// Url {
//   protocol: null,
//   slashes: null,
//   auth: null,
//   host: null,
//   port: null,
//   hostname: null,
//   hash: null,
//   search: null,
//   query: [Object: null prototype] {},
//   pathname: '//foo/bar',
//   path: '//foo/bar',
//   href: '//foo/bar'
// }

  const obj1 = url.parse(str, true, true)
  console.log(obj1);
// Url {
//   protocol: null,
//   slashes: true,
//   auth: null,
//   host: 'foo',
//   port: null,
//   hostname: 'foo',
//   hash: null,
//   search: null,
//   query: [Object: null prototype] {},
//   pathname: '/bar',
//   path: '/bar',
//   href: '//foo/bar'
// }

  差异 host 和 hostname 都被解析出来了

关于 urlObject

protocol  协议 需要注意的是包含了: 并且是小写
slashes   如果:后面跟了两个//  那么为true
auth      认证信息,如果有密码,为 usrname:password, 如果没有,则为 usrname 注意: 这里区别大小写
host      主机名,包含端口 比如 ke.qq.come:8080 并且都是小写
hostname  主机名 不包含端口 并且都是小写
hash      哈希部分 注意包含了#
search    查询字符串 注意 包含了 ? 此外 值是没有经过decode的
query     字符串 或者 对象 如果是字符串 则是 search 去掉 ? 其余一样 如果是对象 那么是decode过的
path      路径部分,包含了search部分
pathname  路径部分 不包含 search 部分
href      原始的地址 不过需要注意的是 protocol host 会被转成小写字母

protocol: 'http:',
slashes: true,
auth: 'Chyingp:HelloWorld',
host: 'ke.qq.com:8080',
port: '8080',
hostname: 'ke.qq.com',
hash: '#part=1',
search: '?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
query: 'nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
pathname: '/index.html',
path: '/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
href: 'http://Chyingp:HelloWorld@ke.qq.com:8080/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1#part=1'

将一个解析后的 URL 对象、转成、一个格式化的 URL 字符串。 url.format(urlObject)

url.parse(str)的反向操作 urlObject包含了很多字段 比如 protocol slashes等,且不一定需要全部传,

const strObject = {
 protocol: 'http:',
 slashes: true,
 auth: 'Chyingp:HelloWorld',
 host: 'ke.qq.com:8080',
 port: '8080',
 hostname: 'ke.qq.com',
 hash: '#part=1',
 search: '?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
 query: 'nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
 pathname: '/index.html',
 path: '/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
 href: 'http://Chyingp:HelloWorld@ke.qq.com:8080/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1#part=1'
}

// http://Chyingp:HelloWorld@ke.qq.com:8080/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1#part=1
console.log(url.format(strObject));

url.resolve(from, to) 用于拼接 URL

const one = url.resolve("/one/two/three", "four"); // /one/two/four
const two = url.resolve("http://baidu.com/", "four"); // http://baidu.com/four
const three = url.resolve("http://baidu.com/one", "four"); // http://baidu.com/four

非法字符转义

url内存在如下的特殊字符会被转移(非法字符)
$lt $gt \r \n \t { } \/ \ ^