🚀 使用的方法:短链接


📖 问题背景
        在我们的城乡改造后台管理系统中,有一个复杂的地区管理模块。用户可以通过多维度条件查询数据:市、区、村、时间范围等。当用户选择多个市,多个区,多个村时,浏览器将市-区-村等筛选条件拼接在Get请求的URL中并发向服务器,因参数过多导致URL长度达到长度限制(通常是2048字符)无法正常发起HTTP请求。(注:HTTP协议规范并未限定URL长度,但实际不同浏览器、nginx、tomcat都对URL长度进行了限制),导致414错误。

🤔 解决方案的权衡
面对这个问题,我们有几个选择:

方案A:改用POST请求

 // 优点:无URL长度限制
// 缺点:破坏RESTful语义,缓存失效,不符合GET的幂等性

方案B:前端分页
// 优点:彻底解决长度问题
 // 缺点:需要大量业务代码改动,用户体验受影响

方案C:短链接方案
 // 优点:
提供短链接接口,原URL作为参数通过POST请求传值到服务器,获取短链接;
接收到短链接
使用该短链接发起请求,服务器内部转发至原URL
成果:不涉及业务调整,解决了问题
数据计算
响应数据处理

成本:
前端需要在迭代请求封装:
后端需要提供短链接服务。

// 缺点:增加网络开销

最终我们选择了方案C,因为它在保持系统设计原则的同时,提供了最佳的用户体验。


💡 核心实现思路


1. 短链接接口设计

//shortLink.js
import request from  "@/utils/request";
import qs from "qs";

export function initsources(data) {
  return request({
    url: '/xx/xx/xx/initsources',
    method: 'post',
    data:qs.stringify(data)
  })
}

2.拦截器处理

重点是判断转码之后的长度!!!

import { initsources} from "@/api/shortLink";

service.interceptors.request.use(async config => {
  if(config.method == 'get'){
     var fullUrl = "";
     const encodedParams = Object.entries(params).map(([key, value]) => {
       if (Array.isArray(value)) {
            return value.map(v =>         
           `${encodeURIComponent(key)}=${encodeURIComponent(v)}`).join('&');
       }
       return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
     }).join('&');

     fullUrl = `${url}?${encodedParams}`;
 
     // 长度检查和处理
     if (fullUrl.length > 2000) {
      let res = await initsources({srcurl: fullUrl })
       config.url = res.data; // 替换为短链接
       config.params = null;
     }
   }
   return config
 })

3.透明替换机制
最巧妙的部分是对业务代码的完全透明:

 // 业务代码完全不需要修改:xxx

// 拦截器自动处理:
// 如果URL > 2000字符 → 调用短链服务 → 替换为短URL
// 如果URL ≤ 2000字符 → 直接发送

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐