// url是否带有host const hasHost = (url) => { return url.indexOf('https') >- 1 || url.indexOf('http') >- 1; } // 解析查询字符串 decodeURIComponent const parseQuery = (query) => { const queryArr = query ? query.split('&') : []; let params = {}; for (var i = 0, n = queryArr.length; i < n; i++) { let arr = queryArr[i].split('='); if(arr.length>0){ let key = decodeURIComponent(arr.shift()); let value = decodeURIComponent(arr.join('=')); // 参数如果带=,在这里加上去 params[key] = value; } } return params; } // 解析路径 // 将类似/a/b/1 解析成 {path:/a/b, params:{id:1}} const parsePath = (path:string, pattern?:string) =>{ const keyArr = pattern ? pattern.split('/') : []; const valueArr = path.split('/'); let pathObj:any = { path, params:{}}; let pathArr = []; for (var i = 0, n = keyArr.length; i < n; i++) { var key = keyArr[i]; var value = valueArr[i]; if(key.indexOf(':') == -1){ if(key == value){ pathArr.push(key); }else{ break; } }else{ var nKey = key.replace(':',''); pathObj.path = pathArr.join('/'); if(value) pathObj.params = {[nKey]:value} } } return pathObj; } const patternToPath = (pattern) => { return pattern.split('/:')[0]; } // 将类似/a/b/1?x=1&y=2 解析成 {path:/a/b, params:{id:1,x:1,y:2}} const parseUrl = (url:string,pattern?:string) => { const arr = url ? url.split('?') : []; let path = arr[0]; let params = parseQuery(arr[1]) || {}; let pathObj = parsePath(path, pattern); pathObj.params = Object.assign({}, pathObj.params, params); return pathObj } /** * 拼接query值 * @param params 参数 * @param isAdd 是否追加 * @returns {string} */ const stringifyQuery = (params, isAdd) => { let query = ''; for (let key of Object.keys(params)) { let value = params[key]; if(value || value == 0) { key = encodeURIComponent(key); value = encodeURIComponent(value); query += ('&' + key + '=' + value); } } return isAdd ? query : query.replace(/&/,'?'); } // 将类似/a/b {x:1}, /a/b/1 {y:2}这样的配置拼接为url // encodeURIComponent const stringifyUrl = (url, params, pattern?) => { const urlObj = parseUrl(url,pattern); // 剔除参数,只留纯路径 let path = urlObj.path; params = Object.assign({}, params, urlObj.params); if(pattern && pattern.indexOf('/:') > -1){ const match = pattern.match(/\/:(.*)/); if(match){ const key = match[1]; const value = params[key]; // 如果params有匹配的参数,则路径添加这个参数,并且从params中删除 if(value || value == 0) { delete params[key]; path = pattern.replace(':' + key, value);// 匹配到/:然后进行替换 } } } const query = stringifyQuery(params, false); return path + query; } export { patternToPath, parsePath, parseUrl, stringifyUrl, hasHost }