如何有效压缩1200-1500个字符的URL?

3

这个问题有很多难点。我需要压缩URI,但是由于其结构不是静态的,所以这很困难:

repos=aaa,bbb,ccc&
labels=ddd,eee,fff&
milestones=ggg,hhh,iii&
username=kkk&
show_open=0&
show_closed=1&
show_commented=1&
show_uncommented=0

提取:

aaa,bbb,ccc|ddd,eee,fff|ggg,hhh,iii|kkk|0110

请求有点像GraphQL,因此我们发送结构并针对该结构有答案。 目前我们使用的压缩仅更改所有请求中的某些措辞(函数:is f:..)。

我们想要进行通用压缩,而不是如果架构发生更改就必须维护的内容(在下面的示例中,我们不想将quizz.campaign更改为#12)。 我们每次连接执行这种类型的请求一到两次,因此下载库以从1500个字符压缩到可能为300个字符的连接最昂贵的是什么还是进行一些通用压缩,例如将[更改为(,将压缩从1500个字符压缩到900个字符。

通用压缩可能看起来像这样:

str.replace(/\*/g, "%#111")
        .replace(/\!/g, "%#222")
        .replace(/\(/g, "%#333")
        .replace(/\)/g, "%#444")
        .replace(/\~/g, "%#555")
        .replace(/\_/g, "%#666")
        .replace(/\'/g, "%#777")
        .replace(/\,/g, "*")
        .replace(/\:/g, "!")
        .replace(/\[/g, "(")
        .replace(/\]/g, ")")
        .replace(/\{/g, "~")
        .replace(/\}/g, "_")
        .replace(/\"/g, "'")
        .replace(/\%#111/g, ",")
        .replace(/\%#222/g, ":")
        .replace(/\%#333/g, "[")
        .replace(/\%#444/g, "]")
        .replace(/\%#555/g, "{")
        .replace(/\%#666/g, "}")
        .replace(/\%#777/g, '"');

一个请求的JSON看起来像这样:

    [{
    "f": "find-qzc-by-id",
    "k": "qzcpn",
    "a": {
        "quizz.campaign/id": "quizz-kdfjdslk"
    },
    "n": [{
        "f": "quizz.campaign/activeQuizzQuestions",
        "k": "quizz.campaign/activeQuizzQuestions",
        "n": ["fanQuestion/id", "fanQuestion/questionText", "fanQuestion/questionType", {
            "f": "fanQuestion/choices",
            "k": "fanQuestion/choices",
            "n": ["quizz.question.choice/bgImg", "fanQuestion.choice/id", "fanQuestion.choice/adminLabel", "fanQuestion.choice/text"]
        }, "bs.model/scid", "bs.model/uiConfig"]
    }, "quizz.campaign/id", "quizz.campaign/gameLogic", "quizz.campaign/quizzConfig", "quizz.campaign/bgImg", "quizz.campaign/previewImage", "quizz.campaign/title", "quizz.campaign/description", "campaign/publicOrganizerName", {
        "f": "campaign/organization",
        "k": "campaign/organization",
        "n": ["org/id"]
    }, "campaign/bsCpnType", "bs.model/scid", "bs.model/uiConfig", "bs.model/bsCustomContent", "bs.time/created", "bs.model/nl"]
}]

然后编码后的请求看起来像这样:
?q=%5B%7B%22f%22%3A%22find-qzc-by-id%22%2C%22k%22%3A%22qzcpn%22%2C%22a%22%3A%7B%22quizz.campaign%2Fid%22%3A%22quizz-kdfjdslk%22%7D%2C%22n%22%3A%5B%7B%22f%22%3A%22quizz.campaign%2FactiveQuizzQuestions%22%2C%22k%22%3A%22quizz.campaign%2FactiveQuizzQuestions%22%2C%22n%22%3A%5B%22fanQuestion%2Fid%22%2C%22fanQuestion%2FquestionText%22%2C%22fanQuestion%2FquestionType%22%2C%7B%22f%22%3A%22fanQuestion%2Fchoices%22%2C%22k%22%3A%22fanQuestion%2Fchoices%22%2C%22n%22%3A%5B%22quizz.question.choice%2FbgImg%22%2C%22fanQuestion.choice%2Fid%22%2C%22fanQuestion.choice%2FadminLabel%22%2C%22fanQuestion.choice%2Ftext%22%5D%7D%2C%22bs.model%2Fscid%22%2C%22bs.model%2FuiConfig%22%5D%7D%2C%22quizz.campaign%2Fid%22%2C%22quizz.campaign%2FgameLogic%22%2C%22quizz.campaign%2FquizzConfig%22%2C%22quizz.campaign%2FbgImg%22%2C%22quizz.campaign%2FpreviewImage%22%2C%22quizz.campaign%2Ftitle%22%2C%22quizz.campaign%2Fdescription%22%2C%22campaign%2FpublicOrganizerName%22%2C%7B%22f%22%3A%22campaign%2Forganization%22%2C%22k%22%3A%22campaign%2Forganization%22%2C%22n%22%3A%5B%22org%2Fid%22%5D%7D%2C%22campaign%2FbsCpnType%22%2C%22bs.model%2Fscid%22%2C%22bs.model%2FuiConfig%22%2C%22bs.model%2FbsCustomContent%22%2C%22bs.time%2Fcreated%22%2C%22bs.model%2Fnl%22%5D%7D%5D

如果您认为使用库是成本问题的更好解决方式,那么您有没有一些推荐的JS压缩和JVM解压缩的库呢?谢谢。

2
如果不知道将使用哪个库(及其大小),我们无法真正回答。在您的情况下,该库是否仅加载一次还是每个请求都加载?如果是前者,则使用库似乎是正确的选择。此外,为什么要进行URL压缩,为什么不使用POST传递数据? - Kaddath
因为在HTML中使用GET更加优化,当您进行任何请求时,除了GET之外,您需要进行2个调用,第一个是OPTIONS类型的请求,然后它执行POST请求。我们真的希望优化所有可以优化的事情。目前我没有想到任何库,但我并不排斥,可能会像lz-string这样的东西。 - user3659739
2
似乎更多关于深奥的优化问题,至少可以肯定的是,这与[jvm]标签完全没有任何关联。 - Holger
好的,我明白了。实际上,在POST中使用OPTIONS方法只会在你设置了自定义头部或者content-type不在某些特定值之间时才会发生,请参见此处 - Kaddath
这仍然取决于库是否只加载一次,用于多个请求还是所有请求。它还取决于你想要关注的是时间还是数据大小。如果实现不太复杂,我建议进行一些基准测试来比较解决方案,通过直接在你的环境中测量你所需的内容(时间/大小),你也可以与提供的gzip进行比较。 - Kaddath
显示剩余2条评论
1个回答

0

仅使用POST不需要OPTION请求,请参考https://dev59.com/UV4c5IYBdhLWcg3wc6Dr#27924344

如果您真的想使用压缩,您不必在JS中执行。 对于“服务器 -> 浏览器”的方向,启用deflate压缩(“Accept-Encoding:deflate”,gzip或br)就足够了,不需要进行任何代码更改,也许只需在服务器配置(apache,tomcat,无论您使用什么)中启用它。

对于“浏览器 -> 服务器”并实际使用查询字符串,使用HTTP 2.0将是最简单的解决方案,因为它压缩了所有标题,包括“Path:”。


这是一个有趣的观点,但由于某些限制,我们必须使用GET方法,特别是对于HTTP缓存等情况。 - user3659739

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接