Excel公式转树对象URL传参过长报错,求替代传输或无损压缩方案
解决方案:替代URL传参或无损压缩JSON
一、改用更适合大数据的传输方式
1. POST请求传递数据(推荐)
彻底避开URL长度限制,将数据通过POST请求传递:
C#端代码修改:
var json = JsonSerializer.Serialize(res); var postData = new Dictionary<string, string> { ["jsonString"] = json, ["lettersFormula"] = lettersFormula }; using var client = new HttpClient(); var content = new FormUrlEncodedContent(postData); // 发送POST请求到React后端API接口 var response = await client.PostAsync("http://localhost:3000/api/receive-formula-tree", content); // 根据后端响应跳转页面,示例为启动浏览器打开跳转地址 var redirectUrl = await response.Content.ReadAsStringAsync(); Process.Start(new ProcessStartInfo(redirectUrl) { UseShellExecute = true });
React端处理:
以Next.js为例,先添加API路由接收POST数据并暂存:
// pages/api/receive-formula-tree.js import { serialize } from 'cookie'; export default async function handler(req, res) { if (req.method === 'POST') { const { jsonString, lettersFormula } = req.body; // 用Cookie暂存数据,也可使用Redis等临时存储方案 const cookie = serialize('formulaData', JSON.stringify({ jsonString, lettersFormula }), { httpOnly: false, path: '/', maxAge: 3600 }); res.setHeader('Set-Cookie', cookie); // 重定向到目标页面 res.redirect('/CreateTreePage'); } else { res.status(405).send('仅支持POST请求'); } }
在CreateTreePage中读取Cookie数据:
useEffect(() => { const getCookie = (name) => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop().split(';').shift(); }; const formulaDataCookie = getCookie('formulaData'); if (formulaDataCookie) { const { jsonString } = JSON.parse(formulaDataCookie); const formulasObjectsArray = JSON.parse(jsonString.replace(/\@/g, "#")); SetArray(formulasObjectsArray); // 用完删除Cookie释放空间 document.cookie = 'formulaData=; path=/; max-age=0'; } }, []);
2. 本地存储中转(C#桌面端+React前端场景)
如果C#是桌面应用,可先将JSON写入浏览器sessionStorage再打开页面:
// 示例用CefSharp嵌入浏览器控件 browser.ExecuteScriptAsync($"sessionStorage.setItem('formulaTreeData', '{JsonSerializer.Serialize(res)}')"); browser.Load("http://localhost:3000/CreateTreePage/?lettersFormula=" + lettersFormula);
React端读取:
useEffect(() => { const jsonString = sessionStorage.getItem('formulaTreeData'); if (jsonString) { const formulasObjectsArray = JSON.parse(jsonString.replace(/\@/g, "#")); SetArray(formulasObjectsArray); sessionStorage.removeItem('formulaTreeData'); } }, []);
二、无损压缩JSON(仍需URL传参时使用)
1. GZip压缩+Base64编码
对JSON进行GZip压缩后转Base64,大幅缩短传输长度:
C#端代码:
var json = JsonSerializer.Serialize(res); byte[] jsonBytes = Encoding.UTF8.GetBytes(json); // GZip压缩 using var memoryStream = new MemoryStream(); using var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress); gZipStream.Write(jsonBytes, 0, jsonBytes.Length); gZipStream.FlushFinalBlock(); byte[] compressedBytes = memoryStream.ToArray(); // Base64编码适配URL传输 var encodedJson = Convert.ToBase64String(compressedBytes); var url = $"http://localhost:3000/CreateTreePage/?jsonString={encodedJson}&lettersFormula={lettersFormula}";
React端解码解压:
useEffect(() => { const { jsonString } = queryString.parse(window.location.search); if (jsonString) { // Base64解码为字节数组 const compressedBytes = Uint8Array.from(atob(jsonString), c => c.charCodeAt(0)); // 浏览器原生GZip解压 const decompress = async (bytes) => { const stream = new Blob([bytes]).stream().pipeThrough(new DecompressionStream('gzip')); const reader = stream.getReader(); const chunks = []; let result; while (!(result = await reader.read()).done) { chunks.push(result.value); } const decompressedBytes = new Uint8Array(chunks.reduce((acc, chunk) => acc.concat(Array.from(chunk)), [])); return new TextDecoder('utf-8').decode(decompressedBytes); }; decompress(compressedBytes).then(decompressedJson => { const formulasObjectsArray = JSON.parse(decompressedJson.replace(/\@/g, "#")); SetArray(formulasObjectsArray); }); } }, []);
2. MessagePack二进制序列化
MessagePack是比JSON更紧凑的二进制序列化格式,支持无损还原:
C#端(需安装MessagePack NuGet包):
// 序列化对象为MessagePack二进制 var packedBytes = MessagePackSerializer.Serialize(res, MessagePack.Resolvers.StandardResolver.Instance); // Base64编码适配URL传输 var encodedData = Convert.ToBase64String(packedBytes); var url = $"http://localhost:3000/CreateTreePage/?data={encodedData}&lettersFormula={lettersFormula}";
React端(需安装@msgpack/msgpack依赖):
import { decode } from '@msgpack/msgpack'; useEffect(() => { const { data } = queryString.parse(window.location.search); if (data) { const packedBytes = Uint8Array.from(atob(data), c => c.charCodeAt(0)); // 直接解码为原对象,无需额外字符替换 const formulasObjectsArray = decode(packedBytes); SetArray(formulasObjectsArray); } }, []);
内容的提问来源于stack exchange,提问作者doxzi
相关产品推荐
相关产品推荐

