You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS:自定义GET查询参数序列化与解析方案(缩短URL)

嘿,我完全懂你想要缩短URL又能优雅传递JSON结构的需求!亚马逊那种紧凑的筛选参数格式确实很实用,下面给你几个更灵活的方案,解决你当前q[1]这类格式的局限性:

1. 扁平化键名方案(推荐,兼顾简洁与兼容性)

这是最接近亚马逊筛选器的格式,核心是把嵌套的JSON结构用.(或者_)拼接键名,数组则直接重复键名传递,不用依赖索引。

比如原JSON:

{
  "filter": {
    "price": {"min": 10, "max": 100},
    "category": ["electronics", "books"]
  }
}

可以转成:
filter.price.min=10&filter.price.max=100&filter.category=electronics&filter.category=books
如果想更短,还可以给常用键名加缩写,比如f.p.min=10&f.p.max=100&f.c=electronics&f.c=books。

优点:

  • URL长度比JSON.stringify短很多,可读性也不错
  • 绝大多数后端框架(比如Express、Django)原生支持解析这种嵌套格式
  • 数组处理更灵活,不用再写q[1]这类索引式的参数,重复键名即可自动被解析为数组

实现示例(JS):

// 序列化:把JSON转成扁平化查询参数
function flattenJSON(obj, prefix = '') {
  const result = {};
  for (const key in obj) {
    const newKey = prefix ? `${prefix}.${key}` : key;
    if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
      // 递归处理嵌套对象
      Object.assign(result, flattenJSON(obj[key], newKey));
    } else if (Array.isArray(obj[key])) {
      // 数组元素重复键名
      obj[key].forEach(item => {
        result[newKey] = result[newKey] ? [...result[newKey], item] : [item];
      });
    } else {
      result[newKey] = obj[key];
    }
  }
  return new URLSearchParams(result).toString();
}

// 解析:把扁平化参数还原为JSON
function unflattenParams(searchParams) {
  const obj = {};
  for (const [key, value] of searchParams.entries()) {
    const keys = key.split('.');
    let current = obj;
    for (let i = 0; i < keys.length; i++) {
      const k = keys[i];
      if (i === keys.length - 1) {
        // 处理数组:重复键名转为数组
        if (current[k]) {
          current[k] = Array.isArray(current[k]) ? [...current[k], value] : [current[k], value];
        } else {
          current[k] = value;
        }
      } else {
        current[k] = current[k] || {};
        current = current[k];
      }
    }
  }
  return obj;
}
2. 自定义缩写编码(极致缩短URL)

如果追求极致的URL长度,可以给常用的键名、枚举值提前约定缩写映射。比如把filter缩写成f,price.min缩写成pm,electronics缩写成e,上面的例子可以进一步压缩成:
fpm=10&fpx=100&fc=e&fc=b

优点:URL长度最短

缺点:需要前后端严格约定映射规则,可读性差,维护成本较高,适合固定结构的场景

3. 轻量级二进制编码(适合复杂大结构)

如果你的JSON结构复杂、数据量较大,可以用MessagePack、BSON这类轻量级二进制编码,再转成URL安全的Base64(把+换成-,/换成_,去掉末尾的=)。

实现示例(JS):

import msgpack from 'msgpack-lite';

// 序列化
function encodeComplexJSON(obj) {
  const buffer = msgpack.encode(obj);
  // 转成URL安全的Base64
  return btoa(String.fromCharCode(...new Uint8Array(buffer)))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
}

// 解析
function decodeComplexJSON(str) {
  // 还原Base64格式
  const restoredStr = str.replace(/-/g, '+').replace(/_/g, '/');
  const buffer = new Uint8Array(atob(restoredStr).split('').map(c => c.charCodeAt(0)));
  return msgpack.decode(buffer);
}

优点:能处理任意复杂JSON,编码后长度远小于JSON.stringify

缺点:URL是一串无意义字符,完全不可读,需要引入第三方编码库

方案选择建议
  • 优先选扁平化键名方案:兼顾简洁、可读性和后端兼容性,解决你之前索引式数组的局限性
  • 极致短URL需求:选自定义缩写编码,但要做好前后端规则同步
  • 复杂大结构:选轻量级二进制编码,适合数据量大但不需要可读URL的场景

内容的提问来源于stack exchange,提问作者JCDenton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:25:03