V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
lzlee
V2EX  ›  问与答

[请教一个可能是前端的问题] URL 里的 queryString 的编码, 通常是怎么确定的

  •  
  •   lzlee · 2018-12-19 22:32:21 +08:00 · 1491 次点击
    这是一个创建于 2191 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    1. 最近在看一本老书 <深入分析 Java Web 技术内幕> 许令波著
    2. 书中 第三章 提到一个 URL 编解码的问题
    3. 作者将 URL 分为了好几块
    4. URL 中大部分是用 UTF-8 编码的
    5. queryString(查询条件), 是用 浏览器默认的编码(书中解释说通常是 GBK)
    6. 书中还说, 如果要把 queryString 也设置为 UTF-8, 那么需要在 requestHeader 里添加 content-type 属性, 并在值中添加 "charset=UTF-8"
    7. 但是我使用 chrome( 71.0.3578.98 版本) 浏览器, 尝试在 百度 和 搜狗 的 request 里, 找这个 content-type, 没有找到
    8. 我发现在 queryString 里有个字段叫做 ie=utf-8
    9. 而且我的查询关键字, 也确实是 utf-8 的 url 编码, 我在在线的工具上转换过

    我的问题

    1. 现在的 queryString 编码通常是怎么定的, 是浏览器还是由其他的配置
    2. 如果是浏览器定的话, 后端是怎么适配各种浏览器的(我不倾向这种方案)
    3. 如果是前端定的, 拿通常是怎么定的(比如 百度 或者 搜狗), 是我的搜索关键字经过 前端 转码后再做的请求吗?
    4. 如果 2 和 3 都假设错了, 那还有别的解决方案吗?

    最后感谢各位大佬的帮助

    16 条回复    2018-12-20 21:25:48 +08:00
    Trim21
        1
    Trim21  
       2018-12-20 04:02:46 +08:00
    1 是 RFC3986 定的
    queryString 的编码不是 unicode, 是部分 ascii
    a-zA-Z0-9 和! * ' ( ) ; : @ & = + $ , / ? # [ ]
    utf8 内容比如汉字应该先通过 urlencode 变成以上的内容
    Trim21
        2
    Trim21  
       2018-12-20 05:04:32 +08:00   ❤️ 1
    @Trim21 #1 又搜了一下, 发现我最后一句话说的不太对.
    应该是对于其他字符, 应该先转成 utf8 ,再通过 urlencode 转成以上的字符
    lzlee
        3
    lzlee  
    OP
       2018-12-20 10:06:17 +08:00
    @Trim21 谢谢大佬, 解决了我部分的疑惑
    yimity
        4
    yimity  
       2018-12-20 10:21:17 +08:00
    如何编码确实是 RFC3986 定义的。
    (以下为猜测,可能是错误的)
    但是具体编成什么码,则各个浏览器可能有不同。
    IE 则使用了 GBK,跟随操作系统编码(早期的 Firefox 应该也是跟随系统的),而 Chrome 等则使用了 UTF8,
    所以在很多系统中,需要对查询字符使用 encodeURIComponent 进行编码,后端才能正确解析。而 JavaScript 的编码使用的就是 utf8.
    azh7138m
        5
    azh7138m  
       2018-12-20 13:12:57 +08:00
    @Trim21 RFC3986 只是说 "e.g., a document charset" ( Page 14 ),w3c 标准给的示例是 utf8。
    浏览器一般按照,Content-Type 里面的 charset,或者系统的 charset 来。
    lzlee
        6
    lzlee  
    OP
       2018-12-20 14:05:28 +08:00
    @yimity
    不考虑 ie, 您大概是这个意思
    1. Chrome 现在的版本, queryString 使用的是 utf-8 的编码
    2. 如果不是 chrome 做的编码解码, 则需要用 js 的 encodeURIComponent 来做编码
    3. encodeURICompoent 使用的 utf-8 来做的编码

    我理解对了吗?
    lzlee
        7
    lzlee  
    OP
       2018-12-20 14:14:24 +08:00
    @azh7138m

    1. 我用的是 win10 系统
    2. 我看 百度 的包, 发现 request 里没有标明 charset, 只有 response 里有
    3. 跟 编码相关的字段, 在 request 的 queryString 里有个 ie 的选项, 值是 utf-8

    我感觉大概的流程是这样
    1. 百度在拼 url 之前, 用 js 来先把 queryString 里的 关键字 做了编码, 然后拼好, 这个 url 里应该已经没有 ios-8859-1 以外的字符了
    2. 浏览器接到 js 拼好的 url 之后, 直接就按 系统的编码 再封道请求里发出去
    azh7138m
        8
    azh7138m  
       2018-12-20 14:34:09 +08:00
    @lzlee 是你当前 HTML 的那个, view-source:https://www.v2ex.com/t/519157 里面那个
    我是这么理解的,错了别打我(
    yimity
        9
    yimity  
       2018-12-20 15:53:49 +08:00
    @lzlee 对的。
    lzlee
        10
    lzlee  
    OP
       2018-12-20 18:00:03 +08:00
    @azh7138m
    可能是我没说清楚, 我看的书里, 大概是这么定义的, 以这个 url 为例: https://www.v2ex.com/t/519157
    1. `https://` 被定义为 schema
    2. `www.v2ex.com` 被定义为 domain, 有的时候, 还会带端口
    3. `t` 被定义为 context
    4. `519157` 被定义为 Pathinfo
    5. `/t/519157` 被定义为 URI, 这部分, 是 utf-8 编码的
    6. queryString, 指的是查询条件, 例如: `https://www.v2ex.com/t/519157?wd=关键字`, `wd=关键字`, 就是 queryString
    7. 书里说, 在 老 firefox 里, queryString 的编码, 和 URI 的编码是不同的(作者的结论, 是在 queryString 里包含了 pathinfo 的值, 最后编码不一样, 得出来的)
    8. 书里说, queryString 的编码, 会在 requestHeader 里带上, 但是我没找见


    感觉:
    1. 你在 8 楼给的 url, 是按照 utf-8 编码的, 这个我确定
    2. 我的疑惑是 ? 后面的 queryString, 用什么方式编码, 是 js 还是 浏览器 做的编码
    3. 我的疑问在 2 楼 和 4 楼 大佬的帮助下已经解决
    4. 感谢你参与讨论

    : )
    lzlee
        11
    lzlee  
    OP
       2018-12-20 18:00:19 +08:00
    @yimity 多谢大佬指点
    azh7138m
        12
    azh7138m  
       2018-12-20 18:51:07 +08:00 via Android
    @lzlee
    https://github.com/muzea/parser/blob/master/sample/rfc1738.ts
    1738 和 3986 我都看过的。

    之所以是 ie,是因为 ie 的行为不太标准,你看 so 的几个讨论说的很清楚了。
    utf8 是 w3c 建议的编码,不是说一定要循序。


    1. 我在 8 楼的 url 返回一个 html,你看里面的内容,有一个标签,<meta http-equiv="content-type" content="text/html; charset=UTF-8"> 大概这个样子,我说的页面的 charset,指的是这里的。
    azh7138m
        13
    azh7138m  
       2018-12-20 18:53:46 +08:00 via Android
    说的严格一点就是,用什么 charset,标准并没有规定,怎么识别,标准也没有规定,utf8 是大家约定俗成。
    lzlee
        14
    lzlee  
    OP
       2018-12-20 19:30:23 +08:00
    @azh7138m

    1. 8 楼的那个 charset 是 html 页面的编码, 这个是给 浏览器 看的,
    2. 我想问的 charset, 大概是服务端接到 request 时候, 用什么编码解析, 当然后面提到大家通常用 utf-8 来解析
    3. 这个是我没说太清楚

    你后面表达的意思, 我大概理解成这样
    1. utf-8 是 w3c 给的建议, 不是要求, 实现可能会有不同, 依据是 rfc 1738 和 rfc 3986
    2. 大部分浏览器还是使用的 utf-8 作为字符集
    3. 我感觉这个算是个大背景, 也是个重要的信息吧

    感谢大佬
    azh7138m
        15
    azh7138m  
       2018-12-20 20:08:57 +08:00
    @lzlee 我知道是给浏览器看的,RFC3986 里面说的 document charset,指的是这个。
    lzlee
        16
    lzlee  
    OP
       2018-12-20 21:25:48 +08:00
    @azh7138m

    好的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3877 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:55 · PVG 08:55 · LAX 16:55 · JFK 19:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.