Repository navigation
Expand file tree
/
Copy pathurl.js
More file actions
161 lines (133 loc) · 3.56 KB
/
Copy pathurl.js
File metadata and controls
161 lines (133 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import { isArray, type, forEach } from './base'
function encode (val) {
return encodeURIComponent(val)
}
function decode (val) {
return decodeURIComponent(val)
}
function isURLSearchParams (val) {
return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams
}
function serialize (params) {
if (isURLSearchParams(params)) {
return params.toString()
}
const parts = []
forEach(params, (val, key) => {
if (typeof val === 'undefined' || val === null) {
return
}
if (isArray(val)) {
key = key + '[]'
}
if (!isArray(val)) {
val = [val]
}
forEach(val, function parseValue (v) {
if (type(v) === 'Date') {
v = v.toISOString()
} else if (type(v) === 'Object') {
v = JSON.stringify(v)
}
parts.push(encode(key) + '=' + encode(v))
})
})
return parts.join('&')
}
function buildUrl (url, params = {}, serializer) {
if (!serializer) {
serializer = serialize
}
const serializedParams = serializer(params)
if (serializedParams) {
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
}
return url
}
// 解析拆分 url 参数
function parseUrl (url) {
const match = /^(.*?)(\?.*?)?(#.*?)?$/.exec(url)
const [fullUrl, baseUrl = '', search = '', hash = ''] = match
const u1 = baseUrl.split('//') // 分割出协议
const protocolReg = /^\w+:$/
const protocol = protocolReg.test(u1[0]) ? u1[0] : ''
const u2 = u1[1] || u1[0] // 可能没有协议
const i = u2.indexOf('/')
const host = i > -1 ? u2.substring(0, i) : u2 // 分割出主机名和端口号
const path = i > -1 ? u2.substring(i) : '' // 分割出路径
const u3 = host.split(':')
const hostname = u3[0]
const port = u3[1] || ''
return { fullUrl, baseUrl, protocol, hostname, port, host, path, search, hash }
}
const specialValues = {
null: null,
true: true,
false: false
}
function parseQuery (query, noDecode = false) {
if (query.slice(0, 1) !== '?') {
throw new Error(
"A valid query string passed to parseQuery should begin with '?'"
)
}
query = query.slice(1)
if (!query) {
return {}
}
if (query.slice(0, 1) === '{' && query.slice(-1) === '}') {
return JSON.parse(query)
}
const queryArgs = query.split(/&/g)
const result = Object.create(null)
queryArgs.forEach((arg) => {
const idx = arg.indexOf('=')
if (idx >= 0) {
let name = noDecode ? arg.slice(0, idx) : decode(arg.slice(0, idx))
let value = noDecode ? arg.slice(idx + 1) : decode(arg.slice(idx + 1))
// eslint-disable-next-line no-prototype-builtins
if (specialValues.hasOwnProperty(value)) {
value = specialValues[value]
}
if (name.slice(-2) === '[]') {
name = name.slice(0, name.length - 2)
if (!Array.isArray(result[name])) {
result[name] = []
}
result[name].push(value)
} else {
result[name] = value
}
} else {
if (arg.slice(0, 1) === '-') {
result[decode(arg.slice(1))] = false
} else if (arg.slice(0, 1) === '+') {
result[decode(arg.slice(1))] = true
} else {
result[decode(arg)] = true
}
}
})
return result
}
function parseUrlQuery (url, noDecode = false) {
let path = url
let query = ''
const queryIndex = url.indexOf('?')
if (queryIndex >= 0) {
path = url.slice(0, queryIndex)
query = url.slice(queryIndex)
}
const queryObj = parseQuery(query || '?', noDecode)
return {
path,
queryObj
}
}
export {
buildUrl,
parseUrl,
parseQuery,
parseUrlQuery,
serialize
}