利用qs库
qs是一个流行的查询参数序列化和解析库。
可以将一个普通的object序列化成一个查询字符串,或者反过来将一个查询字符串解析成一个object,而且支持复杂的嵌套。
并且天然支持urlcode
的编码和解码。非常的实用
至于http为什么需要这个URLcode的编码机制,可以参考这篇文章《你真的了解URLEncode吗?》
web的get请求中一个key有多个value值的情况如何处理
第一种方法:可以自己手写循序出一个字符串
使用URLSearchParams对象来生成带有重复参数名称的URL
function generateURLWithDuplicateParams(baseUrl, params) {
const url = new URL(baseUrl);
const searchParams = new URLSearchParams();
// 遍历参数对象,将参数名和对应的值添加到URLSearchParams对象中
for (const param in params) {
if (Array.isArray(params[param])) {
// 如果参数值是数组,则将每个值分别添加到URLSearchParams对象中
params[param].forEach(value => {
searchParams.append(param, value);
});
} else {
// 如果参数值不是数组,则直接添加到URLSearchParams对象中
searchParams.append(param, params[param]);
}
}
// 将URLSearchParams对象的内容添加到URL对象的查询参数中
url.search = searchParams.toString();
return url.toString();
}
// 示例用法
const baseUrl = "https://example.com/api";
const params = {
key: ["value1", "value2", "value3"],
anotherKey: "singleValue",
};
const generatedUrl = generateURLWithDuplicateParams(baseUrl, params);
console.log(generatedUrl);
上述代码中,generateURLWithDuplicateParams函数接受一个基础URL和一个参数对象作为输入。参数对象中的每个属性表示一个参数名,对应的属性值可以是单个值或者值的数组(用于表示重复参数)。函数会遍历参数对象,将参数名和对应的值添加到URLSearchParams对象中。最后,将URLSearchParams对象的内容添加到URL对象的查询参数中,并返回生成的URL字符串。在示例中,baseUrl为"https://example.com/api",params对象包含了两个参数,“key"和"anotherKey”。其中,“key"参数具有多个值,使用数组表示。生成的URL为"https://example.com/api?key=value1&key=value2&key=value3&anotherKey=singleValue”。你可以根据实际情况调整baseUrl和params对象的内容来生成适合你的URL。
第二种方法:qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
例如:
接口要求为http://localhost.8080/user?ids=1&ids=2&ids=3
let str = Qs.stringify({
ids: this.ids }, {
indices: false });
let res = await DELETE_USERS(str);
//使用删除用户的接口
export const DELETE_USERS = (query:string)=>{
return http.request({
method:'DELETE',
url:API.USERS+'?'+query
})
}
其他的一些用法
可以将一个普通的object序列化成一个查询字符串,或者反过来将一个查询字符串解析成一个object,而且支持复杂的嵌套。一般这样解析的字符串是url字符串,这样比较有意义。
s.parse('x[]=1') // {x: ['1']}
Qs.stringify({
x: [1]}) // x%5B0%5D=1
qs的两个方法都接受一个可选的第二参数,可以让我们对结果进行配置,个人觉得比较有用的有以下几个:
ignoreQueryPrefix
和addQueryPrefix
ignoreQueryPrefix:这个参数可以自动帮我们过滤掉location.search前面的❓,然后再解析,
addQueryPrefix设为true可以在序列化的时候给我们加上?
// 解析
Qs.parse('?x=1') // {?x: "1"}
Qs.parse('?x=1', {
ignoreQueryPrefix: true}) // {x: "1"}
// 序列化
Qs.stringify({
x: "1"}) // x=1
Qs.parse({
x: "1"}, {
addQueryPrefix: true}) // ?x=1
数组解析和序列化
数组序列化有几种方式:indices, brackets, repeat, comma,用来控制字符串的生成格式。来看下面的例子:
qs.stringify({
a: ['b', 'c'] }, {
arrayFormat: 'indices' })
// 'a[0]=b&a[1]=c'
qs.stringify({
a: ['b', 'c'] }, {
arrayFormat: 'brackets' })
// 'a[]=b&a[]=c'
qs.stringify({
a: ['b', 'c'] }, {
arrayFormat: 'repeat' })
// 'a=b&a=c'
qs.stringify({
a: ['b', 'c'] }, {
arrayFormat: 'comma' })
// 'a=b,c'
也就是说它支持嵌套对象向 search-string 的序列化及反序列化。
什么是 search-string? 简单来说地址栏 ?
及后面的参数就是 search-string。
一般来说 search-string 使用的是 URL encode,如果你使用过 URLSearchParams,它支持将简单的扁平化对象序列化成 search-string。但是URLSearchParams操作比较繁琐。直观下我们更希望直接解析得到一个 Plain Object。
import qs from "qs";
var paramsString = "q=URLUtils.searchParams&topic=api";
var query = qs.parse(paramsString);
console.log(query); // {q: "URLUtils.searchParams", topic: "api"}
console.log(qs.stringify(query)); // q=URLUtils.searchParams&topic=api
qs.parse 直接生成了一个 Plain Object,而 qs.stringify 也直接使用 Plain Object 转化成 query-string。
再一大亮点就是 qs 支持嵌套对象的解析。
import qs from "qs";
const obj = {
a: "1", b: {
c: "2" }, c: [1, 2, 3] };
console.log(new URLSearchParams(obj).toString());
// a=1&b=%5Bobject+Object%5D&c=1%2C2%2C3
const objString = qs.stringify(obj, {
allowDots: true });
console.log(objString);
// a=1&b.c=2&c%5B0%5D=1&c%5B1%5D=2&c%5B2%5D=3
console.log(qs.parse(objString, {
allowDots: true }));
// { a: "1", b: { c: "2" }, c: [1, 2, 3] }
可以看到 URLSearchParams 并不直接支持嵌套对象的序列化,产生了错误的结果,而 qs.stringify 正常生成了 query string,但是这里要注意使用了 allowDots 不转译 . 号,那么使用 qs.parse 的使用也需要加上 allowDots 来正常解析字符串。
前端应用不断丰富、完善的今天,页面之间的跳转、衔接是必需的。在跳转路由的时候,我们就需要为即将进入的页面提供一些关键信息,比如某个实体的 id 、表格的查询条件、页码等。使用 search string 也就非常普遍。
根据使用的场景,建议只在跳转之后的第一次渲染获取 search string 的内容并解析出参数对象来初始化页面中的组件,在状态更新的时候使用 history.replace (react-router)更新路由中的 search 参数,通过设定页面中的关键参数,便于用户对链接进行分享时能够正常打开并还原页面状态。