http://www.sdvil.com/%e7%bc%96%e7%a0%81/89
url 编码
通过url可以访问到网络上的内容,通常它的格式是这样的, protocol://domain/path/filename 为了可以在url 上传输数据, 可以在后面加了 ?key=value&key=value , 可以看到 : / ? & 符号是有特殊意义的, 任意的加入这些字符,就有可能改变url 的意义, 这样就需要对这些字符和那些非ascii 字符集的字符进行编码, 以保证url 的正确的传输。
编码有两种方式, 一个是比较老的 %u + unicode 的方式,如中国的unicode编码是4E2D, 56FD , %u4E2D%u56FD 还有一种是 用% 分割编码的方式,比如中国, utf-8 编码为 e4b8 ade5 9bbd 其对应的url 编码为 %E4%B8%AD%E5%9B%BD
这两种方式也是js 里两组函数对字符进行url 编码的结果, escape 和unescape 是第一种方式,encodeURI和decodeURI 是第二种方式。
encodeURIComponent和decodeURIComponent 也是js 里常用的url 编码的函数, 跟encodeURI和decodeURI 这组函数的区别是它们编码的字符更多一点, 看名字就知道,一个是针对组件的, 编码完后可做为 请求数据key value 中的value 用, 还有一个是针对url 来说, 对/ :@ 等不编码, 想想, 要是对这些也编码了, 那这个url 就不能用于请求网络数据了。
下面列出几个函数的安全字符(不编码的字符)
安全字符 | |
escape(69个) | */@+-._0-9a-zA-Z |
encodeURI(82个) | !#$&’()*+,/:;=?@-._~0-9a-zA-Z |
encodeURIComponent(71个) | !’()*-._~0-9a-zA-Z |
也列一些常用的字符编码以备俺查用
! | * | “ | ‘ | ( | ) | ; | : | @ | & |
%21 | %2A | %22 | %27 | %28 | %29 | %3B | %3A | %40 | %26 |
= | + | $ | , | / | ? | % | # | [ | ] |
%3D | %2B | %24 | %2C | %2F | %3F | %25 | %23 | %5B | %5D |
说完这些, 读者对url 编码有一定的了解了吧。
看完这些基础的, 看看浏览器是怎么处理这些数据的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
<?
php
header("Content-type: text/html;
charset
=
gb2312
");
//header("Content-type: text/html;
charset
=
utf
-8");
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""
<
html
>
<
head
>
<
meta
http-equiv
=
"content-type"
content
=
"text/html; charset=utf-8"
/>
<!--<meta http-equiv="content-type" content="text/html; charset=gb2312" />-->
<
title
>Test_encoding</
title
>
</
head
>
<
body
>
<
form
action
=
"test_encoding.html"
method
=
"get"
enctype
=
"application/x-www-form-urlencoded"
>
<
input
type
=
"text"
name
=
"text"
value
=
"中国"
>
<
input
type
=
"file"
name
=
"file"
value
=
""
>
<
p
><
input
type
=
"submit"
value
=
"Continue → GET url"
></
p
>
</
form
>
<
form
action
=
"test_encoding.html"
method
=
"POST"
enctype
=
"application/x-www-form-urlencoded"
>
<
input
type
=
"text"
name
=
"text"
value
=
"中国"
>
<
input
type
=
"file"
name
=
"file"
value
=
""
>
<
p
><
input
type
=
"submit"
value
=
"Continue → GET url"
></
p
>
</
form
>
<
form
action
=
"test_encoding.html"
method
=
"GET"
enctype
=
"multipart/form-data"
>
<
input
type
=
"text"
name
=
"text"
value
=
"中国"
>
<
input
type
=
"file"
name
=
"file"
value
=
""
>
<
p
><
input
type
=
"submit"
value
=
"Continue → GET data"
></
p
>
</
form
>
<
form
action
=
"test_encoding.html"
method
=
"POST"
enctype
=
"multipart/form-data"
>
<
input
type
=
"text"
name
=
"text"
value
=
"中国"
>
<
input
type
=
"file"
name
=
"file"
value
=
""
>
<
p
><
input
type
=
"submit"
value
=
"Continue → GET data"
></
p
>
</
form
>
<
a
href
=
"test_encoding.html?t=中国"
>中国</
a
>
</
body
>
</
html
>
|
这个例子有几个点:
1. 页面编码为 utf-8 , 用get 请求数据 ,抓包可以看到
test_encoding.html?text=%E4%B8%AD%E5%9B%BD&file=D%3A%5C%E4%B8%AD%E5%9B%BD.docx
把页面代码强制改为 gb2312 , 把页面上的文字删除, 重新输入 中国, 抓包可以看到
test_encoding.html?text=%D6%D0%B9%FA&file=
2. 页面编码为 utf-8 ,表单 enctype=”application/x-www-form-urlencoded” 用post 有请求数据, 抓包可以看到
http头:
Content-Type: application/x-www-form-urlencoded
http body:
text=%E4%B8%AD%E5%9B%BD&file=D%3A%5C%E4%B8%AD%E5%9B%BD.docx
把页面代码强制改为 gb2312 , 把页面上的文字删除, 重新输入 中国, 抓包可以看到
text=%D6%D0%B9%FA&file=
3. 页面编码为utf-8 , 表单 enctype=”multipart/form-data”, 用post请求数据, 抓包可以看到
用二进制编辑器可以看到请求的数据就utf-8 编码的数据
把页面代码强制改为 gb2312 , 把页面上的文字删除, 重新输入 中国,抓包可以类似的, 不过用二进制编辑器看到的是 gb2312 编码的
从上面可以看到表单用什么编码请求页面数据取决于当前页面的编码是什么
顺便说一下页面的编码是怎么设定的
一般我们的浏览器的编码一项都是自动检测的,有两个东西可以影响页面编码
1. html 标签中的 meta
2. Http 头的content-type
header(“Content-type: text/html; charset=gb2312″);
这个值的设置优先级高于页面html的设置,我估计是页面在渲染的时候看到http 头告诉浏览器, 这个页面的编码是 gb2312 , 浏览器就使用gb2312 编码页面了, 即使在页面上用meta 告诉页面它的编码是什么, 也是被浏览器给忽略的。