URL 参数处理 #
什么是 URL 参数? #
URL 参数(也称为查询字符串 Query String)是 URL 中 ? 后面的部分,用于向服务器传递数据。
text
https://example.com/search?q=javascript&page=1&size=10
│ │
└─── 查询字符串开始 ────┘
结构:?key1=value1&key2=value2&key3=value3
URL 结构解析 #
text
┌─────────────────────────────────────────────────────────────┐
│ URL 结构 │
├─────────────────────────────────────────────────────────────┤
│ https://example.com:8080/path/page?id=123&name=John#top │
│ └──┬──┘└────┬────┘└─┬┘└───┬───┘└───────┬───────┘└─┬─┘ │
│ 协议 域名 端口 路径 查询参数 锚点 │
└─────────────────────────────────────────────────────────────┘
基础函数 #
getQueryString(name) #
获取 URL 中指定参数的值。
javascript
export const getQueryString = (name) => {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
const r = window.location.search.slice(1).match(reg);
if (r != null) {
return decodeURIComponent(r[2]);
}
return '';
};
使用示例 #
javascript
import { getQueryString } from './utils';
const url = 'https://example.com?id=123&name=John%20Doe&category=js';
window.location.search = '?id=123&name=John%20Doe&category=js';
const id = getQueryString('id');
const name = getQueryString('name');
const category = getQueryString('category');
const notExist = getQueryString('notExist');
console.log(id);
console.log(name);
console.log(category);
console.log(notExist);
实现原理 #
text
正则表达式解析:
┌─────────────────────────────────────────────────────────────┐
│ 正则:(^|&)name=([^&]*)(&|$) │
├─────────────────────────────────────────────────────────────┤
│ (^|&) 匹配参数名前的位置(开头或 & 之后) │
│ name= 匹配参数名和等号 │
│ ([^&]*) 捕获参数值(非 & 的任意字符) │
│ (&|$) 匹配参数值后的位置(& 或结尾) │
└─────────────────────────────────────────────────────────────┘
匹配过程:
?id=123&name=John
└──┘ 匹配 id=123
└────┘ 匹配 name=John
getQueryParam(url) #
获取 URL 中所有参数,返回对象。
javascript
export const getQueryParam = (url) => {
const queryString = (url ? url.split('?')[1] : window.location.search.slice(1)) || '';
const queryParam = queryString.split('&').reduce((acc, item) => {
const [key, value] = item.split('=');
if (key !== '') {
acc[key] = decodeURIComponent(value);
}
return acc;
}, {});
return queryParam;
};
使用示例 #
javascript
import { getQueryParam } from './utils';
const url = 'https://example.com/search?q=javascript&page=1&size=10';
const params = getQueryParam(url);
console.log(params);
const currentParams = getQueryParam();
console.log(currentParams);
处理边界情况 #
javascript
import { getQueryParam } from './utils';
console.log(getQueryParam('https://example.com'));
console.log(getQueryParam('https://example.com?'));
console.log(getQueryParam('https://example.com?key'));
console.log(getQueryParam('https://example.com?key='));
addQueryParam(url, param) #
向 URL 添加或更新参数。
javascript
export const addQueryParam = (url, param) => {
const [baseUrl] = url.split('?');
const queryParam = getQueryParam(url);
const newQueryParam = { ...queryParam, ...param };
const newQueryString = Object.entries(newQueryParam)
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join('&');
return `${baseUrl}?${newQueryString}`;
};
使用示例 #
javascript
import { addQueryParam } from './utils';
const url1 = 'https://example.com/search?q=js';
const newUrl1 = addQueryParam(url1, { page: 1, size: 10 });
console.log(newUrl1);
const url2 = 'https://example.com/search?q=js&page=1';
const newUrl2 = addQueryParam(url2, { page: 2, sort: 'date' });
console.log(newUrl2);
const url3 = 'https://example.com';
const newUrl3 = addQueryParam(url3, { id: 123, name: 'John' });
console.log(newUrl3);
进阶用法 #
构建查询字符串 #
javascript
const buildQueryString = (params) => {
return Object.entries(params)
.filter(([_, value]) => value !== undefined && value !== null)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join('&');
};
buildQueryString({ name: 'John', age: 25, city: '北京' });
解析完整 URL #
javascript
const parseUrl = (url) => {
const parser = document.createElement('a');
parser.href = url;
return {
protocol: parser.protocol,
host: parser.host,
hostname: parser.hostname,
port: parser.port,
pathname: parser.pathname,
search: parser.search,
hash: parser.hash,
params: getQueryParam(url)
};
};
parseUrl('https://example.com:8080/path/page?id=123#top');
URL 编码解码 #
javascript
const original = 'name=张三&city=北京';
const encoded = encodeURIComponent(original);
console.log(encoded);
const decoded = decodeURIComponent(encoded);
console.log(decoded);
编码对比 #
| 方法 | 编码范围 | 适用场景 |
|---|---|---|
| encodeURIComponent | 除 A-Z a-z 0-9 - _ . ! ~ * ' ( ) 外的所有字符 |
参数值编码 |
| encodeURI | 除 A-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) # 外的字符 |
完整 URL 编码 |
| escape(已废弃) | 除 A-Z a-z 0-9 @ * _ + - . / 外的字符 |
不推荐使用 |
javascript
const url = 'https://example.com/search?q=你好世界';
console.log(encodeURI(url));
console.log(encodeURIComponent('你好世界'));
实际应用场景 #
1. 分页导航 #
javascript
import { getQueryString, addQueryParam } from './utils';
class Pagination {
constructor() {
this.currentPage = parseInt(getQueryString('page')) || 1;
this.pageSize = parseInt(getQueryString('size')) || 10;
}
goToPage(page) {
const newUrl = addQueryParam(window.location.href, { page });
window.location.href = newUrl;
}
changeSize(size) {
const newUrl = addQueryParam(window.location.href, { size, page: 1 });
window.location.href = newUrl;
}
getOffset() {
return (this.currentPage - 1) * this.pageSize;
}
}
const pagination = new Pagination();
pagination.goToPage(2);
2. 搜索功能 #
javascript
import { getQueryString, addQueryParam, getQueryParam } from './utils';
class Search {
constructor() {
this.params = getQueryParam();
}
search(keyword) {
const newUrl = addQueryParam(window.location.href, {
q: keyword,
page: 1
});
window.location.href = newUrl;
}
filter(filters) {
const newUrl = addQueryParam(window.location.href, {
...filters,
page: 1
});
window.location.href = newUrl;
}
getSearchParams() {
return {
keyword: getQueryString('q') || '',
category: getQueryString('category') || 'all',
sort: getQueryString('sort') || 'relevance'
};
}
}
3. 表单状态持久化 #
javascript
import { getQueryParam, addQueryParam } from './utils';
class FormState {
constructor(formId) {
this.form = document.getElementById(formId);
this.loadState();
}
loadState() {
const params = getQueryParam();
Object.entries(params).forEach(([key, value]) => {
const input = this.form.querySelector(`[name="${key}"]`);
if (input) {
input.value = value;
}
});
}
saveState() {
const formData = new FormData(this.form);
const params = {};
formData.forEach((value, key) => {
if (value) params[key] = value;
});
const newUrl = addQueryParam(
window.location.pathname,
params
);
window.history.replaceState({}, '', newUrl);
}
}
const form = new FormState('searchForm');
4. 分享链接生成 #
javascript
import { addQueryParam } from './utils';
const generateShareLink = (baseUrl, data) => {
return addQueryParam(baseUrl, {
ref: 'share',
uid: data.userId,
ts: Date.now()
});
};
const shareLink = generateShareLink('https://example.com/article/123', {
userId: 'user_001'
});
console.log(shareLink);
性能优化 #
缓存解析结果 #
javascript
const queryParamsCache = new Map();
export const getQueryParamCached = (url) => {
const cacheKey = url || window.location.href;
if (queryParamsCache.has(cacheKey)) {
return queryParamsCache.get(cacheKey);
}
const params = getQueryParam(url);
queryParamsCache.set(cacheKey, params);
return params;
};
批量参数处理 #
javascript
export const getMultipleQueryStrings = (names) => {
const params = getQueryParam();
return names.reduce((result, name) => {
result[name] = params[name] || '';
return result;
}, {});
};
const { id, name, page } = getMultipleQueryStrings(['id', 'name', 'page']);
console.log(id, name, page);
常见问题 #
1. 中文乱码问题 #
javascript
import { getQueryString } from './utils';
const url = 'https://example.com?name=%E5%BC%A0%E4%B8%89';
window.location.search = '?name=%E5%BC%A0%E4%B8%89';
const name = getQueryString('name');
console.log(name);
2. 数组参数处理 #
javascript
const getArrayParam = (name) => {
const params = getQueryParam();
const value = params[name];
if (!value) return [];
return Array.isArray(value) ? value : [value];
};
const parseArrayParams = (url) => {
const queryString = url.split('?')[1] || '';
const params = {};
queryString.split('&').forEach(item => {
const [key, value] = item.split('=');
if (key.endsWith('[]')) {
const realKey = key.slice(0, -2);
if (!params[realKey]) params[realKey] = [];
params[realKey].push(decodeURIComponent(value));
} else {
params[key] = decodeURIComponent(value);
}
});
return params;
};
3. 特殊字符处理 #
javascript
const safeGetQueryString = (name) => {
try {
return getQueryString(name);
} catch (e) {
console.error('URL 参数解析错误:', e);
return '';
}
};
下一步 #
现在你已经掌握了 URL 参数处理,接下来学习 Cookie 操作,了解客户端存储的另一种方式!
最后更新:2026-04-04