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

2018-12-19 22:32:21 +08:00
 lzlee

背景

  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 都假设错了, 那还有别的解决方案吗?

最后感谢各位大佬的帮助

1398 次点击
所在节点    问与答
16 条回复
Trim21
2018-12-20 04:02:46 +08:00
1 是 RFC3986 定的
queryString 的编码不是 unicode, 是部分 ascii
a-zA-Z0-9 和! * ' ( ) ; : @ & = + $ , / ? # [ ]
utf8 内容比如汉字应该先通过 urlencode 变成以上的内容
Trim21
2018-12-20 05:04:32 +08:00
@Trim21 #1 又搜了一下, 发现我最后一句话说的不太对.
应该是对于其他字符, 应该先转成 utf8 ,再通过 urlencode 转成以上的字符
lzlee
2018-12-20 10:06:17 +08:00
@Trim21 谢谢大佬, 解决了我部分的疑惑
yimity
2018-12-20 10:21:17 +08:00
如何编码确实是 RFC3986 定义的。
(以下为猜测,可能是错误的)
但是具体编成什么码,则各个浏览器可能有不同。
IE 则使用了 GBK,跟随操作系统编码(早期的 Firefox 应该也是跟随系统的),而 Chrome 等则使用了 UTF8,
所以在很多系统中,需要对查询字符使用 encodeURIComponent 进行编码,后端才能正确解析。而 JavaScript 的编码使用的就是 utf8.
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
2018-12-20 14:05:28 +08:00
@yimity
不考虑 ie, 您大概是这个意思
1. Chrome 现在的版本, queryString 使用的是 utf-8 的编码
2. 如果不是 chrome 做的编码解码, 则需要用 js 的 encodeURIComponent 来做编码
3. encodeURICompoent 使用的 utf-8 来做的编码

我理解对了吗?
lzlee
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
2018-12-20 14:34:09 +08:00
@lzlee 是你当前 HTML 的那个, view-source:https://www.v2ex.com/t/519157 里面那个
我是这么理解的,错了别打我(
yimity
2018-12-20 15:53:49 +08:00
@lzlee 对的。
lzlee
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
2018-12-20 18:00:19 +08:00
@yimity 多谢大佬指点
azh7138m
2018-12-20 18:51:07 +08:00
@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
2018-12-20 18:53:46 +08:00
说的严格一点就是,用什么 charset,标准并没有规定,怎么识别,标准也没有规定,utf8 是大家约定俗成。
lzlee
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
2018-12-20 20:08:57 +08:00
@lzlee 我知道是给浏览器看的,RFC3986 里面说的 document charset,指的是这个。
lzlee
2018-12-20 21:25:48 +08:00
@azh7138m

好的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/519157

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX