Http 简介
http 是一种基于tcp/ip 的应用层协议,全称HyperText Transfer Protocol,超文本传输协议。Http 是客户端和服务端请求和应答的标准,对于来自客户端的每一个请求都会有一个与之对应的响应。
Http协议包含两部分,一是请求体,另一个是响应体。请求体包含请求行、请求头、主体。响应体包含状态行、消息报头和响应正文。
请求:
响应:
了解了Http基本结构之后,我们再来聊聊Http编码的问题。在我们实际开发过程中总会被一些编码问题搞的手足无措,例如:下载附件的附件中文名称乱码、访问地址中的中文乱码、请求或响应中的乱码等。接下来就让我们一起分析一下这些问题。
URL中的乱码问题
URL 语法组成
protocol://hostname[:port]/path[?query][#fragment]
URL中合法字符
- 预留字符
“:” , “/” , “?” , “#” ,"[" / “]” , “@”
“!” , “$” , “&” , “’” , “(” , “)”
“*” , “+” , “,” , “;” , “=” - 特殊字符
+、空格、/、?、%、#、&、= - ASCII中的打印字符
Http协议中请求体的请求行和请求头只能出现规定的合法字符,如果出现不安全的非法字符就需要通过一定的编码方式转为合法字符。如果URL中包含非法字符就需要通过URL编码将非法字符转为合法字符。但是不同浏览器对url中不安全的非法子字符进行url编码时处理的方式有所差异。
如:http://localhost/你/index.html。 浏览器是将非ASCII字符以UTF-8的编码然后进行url编码。最后服务端接收的请求路径为 http://localhost/你/index.html
如:http://localhost/?你 。 chrome 浏览器会将字符以UTF-8的编码然后进行url编码,IE浏览器会将字符以GBK编码然后进行url编码。
注:“非ASCII字符” 说法不太准确,
请求头中的乱码问题(Content-Disposition)
在响应头中Content-Disposition 头中指定附件名称时经常出现乱码。
在Content-Disposition中指定编码方式:
Content-Disposition: attachment;filename="EURO rates";filename*=utf-8''%e2%82%ac%20rates
主体中的乱码问题
请求体或响应体中的主体编码方式是通过请求头或响应头中的Content-Type 来指定的,例如:Content-Type: text/html; charset=utf-8,指定了主体部分是编码为UTF-8的文本。如果我们接收到的主体内容出现乱码就需要检查程序解码设置是否正确。
参考资料
*[RFC 5987] https://tools.ietf.org/html/rfc5987
*[RFC 6266] https://tools.ietf.org/html/rfc6266
*[MDN web docs] https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Disposition