Encoding and status codes

1. Introduction to URL

Overview

URL is the abbreviation of "Uniform Resource Locator", which is translated into Chinese as "website address" and represents the Internet address of various resources. The following are the syntax rules of URLs.

scheme://host.domain:port/path/filename?parameter#anchor

illustrate:

    • scheme - defines the type of Internet service (protocol), the most common types are http, https (the protocol is followed by ://, note: other protocols are not necessarily required, such as the email address protocol, there is only a colon after the protocol name, such as: mailto:[email protected])
    • host - defines the domain host (the default host for http is www)
    • domain - defines an Internet domain name, such as baidu.com
    • :port - defines the port number on the host (the default port number for http is 80)
    • path - defines the path on the server (if omitted, the document must be in the root of the website)
    • filename - defines the name of the document/resource
    • parameter - Define query parameters (the position of the parameter is separated by ? after the path. There can be one or more groups. Each group of parameters is in the form of a key-value pair, such as: key1=value1; multiple groups of parameters are connected by &. Such as: key1=value1&key2=value2)
    • Anchor - Define the anchor point (the anchor point inside the web page, use # plus the anchor name, the anchor name is named through the id attribute of the web page element)
URL characters

Only the following characters can be used for each component of the URL.

  • 26 English letters (including uppercase and lowercase)

  • 10 Arabic numerals

  • Conjunction ( -)

  • Dot( .)

  • Underline ( _)

In addition, there are 18 characters that are reserved characters in the URL and can only appear in a given position. For example, the beginning of the query parameter is a question mark ( ?), which means that the question mark can only appear at the beginning of the query parameter. It is illegal if it appears in other positions and will cause URL parsing errors. Other parts of the URL that use these reserved characters must use their escaped forms.

URL characters are escaped by preceding the hexadecimal ASCII code of these characters with a percent sign ( %). URL cannot contain spaces. URL encoding usually uses + to replace spaces. Below are these 18 characters and their escaped forms.

  • !:%21
  • #:%23
  • $:%24
  • &:%26
  • ':%27
  • (:%28
  • ):%29
  • *:%2A
  • +:%2B
  • ,:%2C
  • /:%2F
  • ::%3A
  • ;:%3B
  • =:%3D
  • ?:%3F
  • @:%40
  • [:%5B
  • ]:%5D

For example, if the URL of a web page is foo?bar.html, that is, the file contains a question mark, it needs to be written as foo%3Fbar.html.

This escape method can actually be used for legal characters in URLs, but it is not recommended. For example, athe hexadecimal ASCII code of a letter is 61, and the escaped form is %61. Therefore, www.apple.comit can be written as www.%61pple.com, and the browser can recognize it.

It is worth noting that the escaped form of spaces is %20. This escaping is necessary for file names that contain spaces.

Other characters (such as Chinese characters) that are neither legal characters nor reserved characters theoretically do not need to be escaped manually and can be written directly in the URL. For example www.example.com/中国.html, the browser will automatically escape them and send them to the server. The escaping method is to use the hexadecimal UTF-8 encoding of these characters, count each two digits as a group, and then add a percent sign ( %) to the header of each group.

For example, the UTF-8 hexadecimal encoding of Chinese characters is e4b8ada group of two characters, which is after URL escape %e4%b8%ad. In other words, wherever there are Chinese characters in the URL , they must be written %e4%b8%ad. Therefore, to access www.example.com/中国.htmlthis URL, you need to write it as follows.

www.example.com/%e4%b8%ad%e5%9b%bd.html
URL encoding reference manual
ASCII characters URL-encoding ASCII characters URL-encoding
space %20 P %50
! %21 Q %51
" %22 R %52
# %23 S %53
$ %24 T %54
% %25 U %55
& %26 V %56
%27 W %57
( %28 X %58
) %29 Y %59
* %2A Z %5A
+ %2B [ %5B
, %2C \ %5C
- %2D ] %5D
. %2E ^ %5E
/ %2F _ %5F
0 %30 ` %60
1 %31 a %61
2 %32 b %62
3 %33 c %63
4 %34 d %64
5 %35 e %65
6 %36 f %66
7 %37 g %67
8 %38 h %68
9 %39 i %69
: %3A j %6A
; %3B k %6B
< %3C l %6C
= %3D m %6D
> %3E n %6E
? %3F o %6F
@ %40 p %70
A %41 q %71
B %42 r %72
C %43 s %73
D %44 t %74
E %45 u %75
F %46 v %76
G %47 w %77
H %48 x %78
I %49 y %79
J %4A z %7A
K %4B { %7B
L %4C | %7C
M %4D } %7D
N %4E ~ %7E
O %4F %7F
Absolute URLs and relative URLs

URLs are divided into two types: absolute URLs and relative URLs.

Absolute URL means that the location of the resource can be determined solely by the URL itself. This means that the URL must carry complete information about the resource, including protocol, host, path, etc. The previous examples are all absolute URLs.

Relative URL means that the URL does not contain all the information about the location of the resource and must be combined with the location of the current web page to locate the resource. For example, the URL of the current web page is https://www.example.com/path/index.html, there is a resource on the web page, the URL points to it a.html, this is a relative URL. Because we only know a.htmlthat we cannot locate resources. The browser assumes that a.htmlit is under the same subdirectory as the current URL and thus obtains the absolute URL https://www.example.com/path/a.html.

If a relative URL /starts with a slash ( ), it represents the root directory of the website. Otherwise, the location of the resource must be calculated using the current directory as the starting point. For example, a relative URL /foo/bar.htmlrepresents a subdirectory of the website's root directory foo, foo/bar.htmlwhich represents a subdirectory of the current directory foo.

URLs can also use two special abbreviations to indicate a specific location.

  • .: Indicates the current directory, such as ./a.html(files in the current directory a.html)
  • ..: Indicates the upper-level directory, such as ../a.html(files under the upper-level directory a.html)

These two abbreviations can be used in multiple combinations, for example, ../../to represent the upper two-level directories.

Absolute URLs can also use these two abbreviations, for example, www.example.com/./index.htmlequal to www.example.com/index.html, which .is equivalent to the current directory of the root directory, that is, the root directory itself.

2. ASCII code and non-ASCII code

ASCII code

我们知道,计算机内部,所有信息最终都是一个二进制值。每一个二进制位(bit)有01两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从0000000011111111

上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为 ASCII 码,一直沿用至今。

ASCII 码一共规定了128个字符的编码,比如空格SPACE是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的一位统一规定为0

ASCII 可打印的字符
字符 编号 描述 字符 编号 描述
32 空格(space) Q 81 大写字母 Q
! 33 感叹号(exclamation mark) R 82 大写字母 R
" 34 引号(quotation mark) S 83 大写字母 S
# 35 数字符号(number sign) T 84 大写字母 T
$ 36 美元符号(dollar sign) U 85 大写字母 U
% 37 百分比符号(percent sign) V 86 大写字母 V
& 38 & 符号(ampersand) W 87 大写字母 W
39 撇号(apostrophe) X 88 大写字母 X
( 40 左括号(left parenthesis) Y 89 大写字母 Y
) 41 右括号(right parenthesis) Z 90 大写字母 Z
* 42 星号(asterisk) [ 91 左方括号(left square bracket)
+ 43 加号(plus sign) \ 92 反斜线(backslash)
, 44 逗号(comma) ] 93 右方括号(right square bracket)
- 45 连字符(hyphen) ^ 94 插入符号(caret)
. 46 句号(period) _ 95 下划线(underscore)
/ 47 斜线(slash) ` 96 重音符(grave accent)
0 48 数字 0 a 97 小写字母 a
1 49 数字 1 b 98 小写字母 b
2 50 数字 2 c 99 小写字母 c
3 51 数字 3 d 100 小写字母 d
4 52 数字 4 e 101 小写字母 e
5 53 数字 5 f 102 小写字母 f
6 54 数字 6 g 103 小写字母 g
7 55 数字 7 h 104 小写字母 h
8 56 数字 8 i 105 小写字母 i
9 57 数字 9 j 106 小写字母 j
: 58 冒号(colon) k 107 小写字母 k
; 59 分号(semicolon) l 108 小写字母 l
< 60 小于号(less-than) m 109 小写字母 m
= 61 等于号(equals-to) n 110 小写字母 n
> 62 大于号(greater-than) o 111 小写字母 o
? 63 问号(question mark) p 112 小写字母 p
@ 64 @ 符号(at sign) q 113 小写字母 q
A 65 大写字母 A r 114 小写字母 r
B 66 大写字母 B s 115 小写字母 s
C 67 大写字母 C t 116 小写字母 t
D 68 大写字母 D u 117 小写字母 u
E 69 大写字母 E v 118 小写字母 v
F 70 大写字母 F w 119 小写字母 w
G 71 大写字母 G x 120 小写字母 x
H 72 大写字母 H y 121 小写字母 y
I 73 大写字母 I z 122 小写字母 z
J 74 大写字母 J { 123 左花括号(left curly brace)
K 75 大写字母 K | 124 竖线(vertical bar)
L 76 大写字母 L } 125 右花括号(right curly brace)
M 77 大写字母 M ~ 126 波浪线(tilde)
N 78 大写字母 N
O 79 大写字母 O
P 80 大写字母 P
ASCII 设备控制字符

ASCII 控制字符(00-31,加上 127)最初被设计用来控制诸如打印机和磁带驱动器之类的硬件设备。

控制字符(除了水平制表符、换行、回车之外)在 HTML 文档中不起任何作用。

字符 编号 描述
NUL 00 空字符(null character)
SOH 01 标题开始(start of header)
STX 02 正文开始(start of text)
ETX 03 正文结束(end of text)
EOT 04 传输结束(end of transmission)
ENQ 05 请求(enquiry)
ACK 06 收到通知/响应(acknowledge)
BEL 07 响铃(bell)
BS 08 退格(backspace)
HT 09 水平制表符(horizontal tab)
LF 10 换行(line feed)
VT 11 垂直制表符(vertical tab)
FF 12 换页(form feed)
CR 13 回车(carriage return)
SO 14 不用切换(shift out)
SI 15 启用切换(shift in)
DLE 16 数据链路转义(data link escape)
DC1 17 设备控制 1(device control 1)
DC2 18 设备控制 2(device control 2)
DC3 19 设备控制 3(device control 3)
DC4 20 设备控制 4(device control 4)
NAK 21 拒绝接收/无响应(negative acknowledge)
SYN 22 同步空闲(synchronize)
ETB 23 传输块结束(end transmission block)
CAN 24 取消(cancel)
EM 25 已到介质末端/介质存储已满(end of medium)
SUB 26 替补/替换(substitute)
ESC 27 溢出/逃离/取消(escape)
FS 28 文件分隔符(file separator)
GS 29 组分隔符(group separator)
RS 30 记录分隔符(record separator)
US 31 单元分隔符(unit separator)
DEL 127 删除(delete)
非 ASCII 编码

英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。比如,在法语中,字母上方有注音符号,它就无法用 ASCII 码表示。于是,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。比如,法语中的é的编码为130(二进制10000010)。这样一来,这些欧洲国家使用的编码体系,可以表示最多256个符号。

但是,这里又出现了新的问题。不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (ג),在俄语编码中又会代表另一个符号。但是不管怎样,所有这些编码方式中,0–127表示的符号是一样的,不一样的只是128–255的这一段。

至于亚洲国家的文字,使用的符号就更多了,汉字就多达10万左右。一个字节只能表示256种符号,肯定是不够的,就必须使用多个字节表达一个符号。比如,简体中文常见的编码方式是 GB2312,使用两个字节表示一个汉字,所以理论上最多可以表示 256 x 256 = 65536 个符号。

三、Unicode

世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。

可以想象,如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是 Unicode,就像它的名字都表示的,这是一种所有符号的编码。

Unicode 当然是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母AinU+0041表示英语的大写字母AU+4E25表示汉字。具体的符号对应表,可以查询unicode.org,或者专门的汉字对应表

**注意:**Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

比如,汉字的 Unicode 是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说,这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。

这里就有两个严重的问题,第一个问题是,如何才能区别 Unicode 和 ASCII ?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果 Unicode 统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

它们造成的结果是:1)出现了 Unicode 的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示 Unicode。2)Unicode 在很长一段时间内无法推广,直到互联网的出现。

四、UTF-8

互联网的普及,强烈要求出现一种统一的编码方式。UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。其他实现方式还包括 UTF-16(字符用两个字节或四个字节表示)和 UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8 是 Unicode 的实现方式之一。

UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

UTF-8 的编码规则很简单,只有二条:

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。

2)对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

下表总结了编码规则,字母x表示可用编码的位。

Unicode符号范围     |        UTF-8编码方式
(十六进制)        |              (二进制)
----------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
范围:0-127
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
范围:128-2047
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
范围:2048-65535
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
范围:65536-1114111

跟据上表,解读 UTF-8 编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。

下面,还是以汉字为例,演示如何实现 UTF-8 编码。

的 Unicode 是4E25100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800 - 0000 FFFF),因此的 UTF-8 编码需要三个字节,即格式是1110xxxx 10xxxxxx 10xxxxxx。然后,从的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,的 UTF-8 编码是11100100 10111000 10100101,转换成十六进制就是E4B8A5

五、HTML 字符编码/HTML实体编码

简介

网页包含了大量的文字,浏览器必须知道这些文字的编码方法,才能把文字还原出来。

一般情况下,服务器向浏览器发送 HTML 网页文件时,会通过 HTTP 头信息,声明网页的编码方式。

Content-Type: text/html; charset=UTF-8

上面代码中,HTTP 头信息的Content-Type字段先声明,服务器发送的数据类型是text/html(即 HTML 网页),然后声明网页的文字编码是UTF-8

网页内部也会再用<meta>标签,再次声明网页的编码。

<meta charset="UTF-8">
字符的数字表示法

网页可以使用不同语言的编码方式,但是最常用的编码是 UTF-8。UTF-8 编码是 Unicode 字符集的一种表达方式。这个字符集的设计目标是包含世界上的所有字符,目前已经收入了十多万个字符。

每个字符有一个 Unicode 号码,称为码点(code point)。如果知道码点,就能查到这是什么字符。举例来说,英文字母a的码点是十进制的97(十六进制的61),汉字“中”的码点是十进制的20013(十六进制的4e2d)。

由于下面的原因,不是每一个 Unicode 字符都能直接在 HTML 语言里面显示。

(1)不是每个 Unicode 字符都可以打印出来,有些没有可打印形式,比如换行符的码点是十进制的10(十六进制的A),就没有对应的字面形式。

(2)小于号(<)和大于号(>)用来定义 HTML 标签,其他需要用到这两个符号的场合,必须防止它们被解释成标签。

(3)由于 Unicode 字符太多,无法找到一种输入法,可以直接输入所有这些字符。换言之,没有一种键盘,有办法输入所有符号。

(4)网页不允许混合使用多种编码,如果使用 UTF-8 编码的同时,又想插入其他编码的字符,就会很困难。

HTML 为了解决上面这些问题,允许使用 Unicode 码点表示字符,浏览器会自动将码点转成对应的字符。

字符的码点表示法是&#N;(十进制,N代表码点)或者&#xN;(十六进制,N代表码点),比如,字符a可以写成&#97;(十进制)或者&#x61;(十六进制),字符可以写成&#20013;(十进制)或者&#x4e2d;(十六进制),浏览器会自动转换它们。

<p>hello</p>
<!-- 等同于 -->
十进制
<p>&#104;&#101;&#108;&#108;&#111;</p>
<!-- 等同于 -->
十六进制
<p>&#x68;&#x65;&#x6c;&#x6c;&#x6f;</p>

上面代码中,字符可以直接表示,也可以使用十进制码点或十六进制码点表示。

注意,HTML 标签本身不能使用码点表示,否则浏览器会认为这是所要显示的文本内容,而不是标签。比如,<p>一旦写成<&#112;>或者&#60;&#112;&#62;,浏览器就不再认为这是标签了,而会当作文本内容将其显示为<p>

字符的实体表示法

数字表示法的不方便之处,在于必须知道每个字符的码点,很难记忆。为了能够快速输入,HTML 为一些特殊字符,规定了容易记忆的名字,允许通过名字来表示它们,这称为实体表示法(entity)。

实体的写法是&name;,其中的name是字符的名字。下面是其中一些特殊字符,及其对应的实体。

  • <&lt;
  • >&gt;
  • "&quot;
  • '&apos;
  • &&amp;
  • ©&copy;
  • #&num;
  • §&sect;
  • ¥&yen;
  • $&dollar;
  • £&pound;
  • ¢&cent;
  • %&percnt;
  • *$ast;
  • @&commat;
  • ^&Hat;
  • ±&plusmn;
  • 空格:&nbsp;

注意,上面最后一个特殊字符是空格,它也有对应的实体表示法。

字符的数字表示法和实体表示法,都可以表示正常情况无法输入的字符,逃脱了浏览器的限制,所以英语里面称为“escape”,中文翻译为“字符的转义”。

六、HTTP 状态码

当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含 HTTP 状态码的信息头(server header)用以响应浏览器的请求。

HTTP 状态码的英文为 HTTP Status Code

下面是常见的 HTTP 状态码:

  • 200 - 请求成功
  • 301 - 资源(网页等)被永久转移到其它URL
  • 404 - 请求的资源(网页等)不存在
  • 500 - 内部服务器错误
HTTP 状态码分类

HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型。响应分为五类:信息响应(100–199),成功响应(200–299),重定向(300–399),客户端错误(400–499)和服务器错误 (500–599):

分类 分类描述
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误
HTTP状态码列表
状态码 状态码英文名称 中文描述
100 Continue 继续。客户端应继续其请求
101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
200 OK 请求成功。一般用于GET与POST请求
201 Created 已创建。成功请求并创建了新的资源
202 Accepted 已接受。已经接受请求,但未处理完成
203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 Partial Content 部分内容。服务器成功处理了部分GET请求
300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305 Use Proxy 使用代理。所请求的资源必须通过代理访问
306 Unused 已经被废弃的HTTP状态码
307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
400 Bad Request 客户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
402 Payment Required 保留,将来使用
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
405 Method Not Allowed 客户端请求中的方法被禁止
406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求
407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
409 Conflict 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突
410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed 客户端请求信息的先决条件错误
413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足Expect的请求头信息
500 Internal Server Error 服务器内部错误,无法完成请求
501 Not Implemented 服务器不支持请求的功能,无法完成请求
502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理
浅析http状态码301、302、303、307、308区别

http的重定向我们经常是张口就来,整个流程也非常简单,服务端HTTP返回码是30x,头里面的Location字段代表新的URL。如下图所示:

在这里插入图片描述

但重定向也还是有需要深入探讨地方,返回码不仅有我们经常使用301和303还有302 307 308 它们有啥区别呢。可以按照是否缓存和重定向方法,两个维度去拆分。

缓存(永久重定向) 不缓存(临时重定向)
转GET 301 302、303
方法保持 308 307

如果是永久重定向那么浏览器客户端就会缓存此次重定向结果,下次如果有请求则直接从缓存读取,譬如我们切换域名,将所有老域名的流量转入新域名,可以使用永久重定向。

如果只是临时重定向那么浏览器则不会缓存,譬如我们的服务临时升级,会使用临时重定向。

方法保持的意思是原请求和重定向的请求是否使用相同的方法,譬如原请求是POST提交一个表单,如果是301重定向的话,重定向的请求会转为GET重新提交,如果是308则会保持原来POST请求不变。

RFC协议规范

  • 301 Moved Permanently,永久重定向
  • 302 Found
  • 303 See Other
  • 307 Temporary Redirect
  • 308 Permanent Redirect 永久重定向

基本结论

  • 3XX开头的HTTP状态码都表示重定向的响应。
  • 301、308是永久重定向;302、303、307是临时重定向。
  • 301、302是http 1.0的内容,303、307、308是http1.1的内容。
  • 301和302本来在http/1.0规范中是不允许重定向时改变请求method的(将POST改为GET),实际许多浏览器实现的时候允许重定向时改变请求method。这就出现了规范和实现不一致的问题
  • 302,303,307的出现,都是基于HTTP/1.1兼容HTTP/1.0规范和实现的差异性;
    • 303的出现是允许重定向时改变请求method
    • 307、308则不允许重定向时改变请求method
    • 此外303响应禁止被缓存。
HTTP/1.0

301

301状态码在HTTP 1.0和HTTP 1.1规范中均代表永久重定向,对于资源请求,原来的url和响应头中location的url而言,资源应该对应location中的url。对于post请求的重定向,还是需要用户确认之后才能重定向,并且应该以post方法发出重定向请求。

关于post请求重定向用户确认的问题,实际上浏览器都没有实现;而且post请求的重定向应该发起post请求,这里浏览器也并不一定遵守,所以说HTTP规范的实现并未严格按照HTTP规范的语义。

在301中资源对应的路径修改为location的url,在SEO中并未出现问题,但是在302中就出现了302劫持问题

302

在http 1.0规范中,302表示临时重定向,location中的地址不应该被认为是资源路径,在后续的请求中应该继续使用原地址。

  • 规范
    • 原请求是post,则不能自动进行重定向;原请求是get,可以自动重定向;
  • 实现
    • 浏览器和服务器的实现并没有严格遵守HTTP中302的规范,服务器不加遵守的返回302,浏览器即便原请求是post也会自动重定向,导致规范和实现出现了二义性,由此衍生了一些问题,譬如302劫持,因此在HTTP 1.1中将302的规范细化成了303和307,希望以此来消除二义性。
  • 302劫持
    • A站通过重定向到B站的资源xxoo,A站实际上什么都没做但是有一个比较友好的域名,web资源xxoo存在B站并由B站提供,但是B站的域名不那么友好,因此对搜索引擎而言,可能会保存A站的地址对应xxoo资源而不是B站,这就意味着B站出了资源版权、带宽、服务器的钱,但是用户通过搜索引擎搜索xxoo资源的时候出来的是A站,A站什么都没做却被搜索引擎广而告之用户,B站做了一切却不被用户知道,价值被A站窃取了。
HTTP/1.1

301

和http 1.0规范中保持一致,注意资源对应的路径应该是location中返回的url,而不再是原请求地址。

302

在HTTP 1.1中,实际上302是不再推荐使用的,只是为了兼容而作保留。规范中再次重申只有当原请求是GET or HEAD方式的时候才能自动的重定向,为了消除HTTP 1.0中302的二义性,在HTTP 1.1中引入了303和307来细化HTTP 1.0中302的语义。

303

在HTTP 1.0的时候,302的规范是原请求是post不可以自动重定向,但是服务器和浏览器的实现是运行重定向。

把HTTP 1.0规范中302的规范和实现拆分开,分别赋予HTTP 1.1中303和307,因此在HTTP 1.1中,303继承了HTTP 1.0中302的实现(即原请求是post,也允许自动进行重定向,结果是无论原请求是get还是post,都可以自动进行重定向),而307则继承了HTTP 1.0中302的规范(即如果原请求是post,则不允许进行自动重定向,结果是post不重定向,get可以自动重定向)

307

在http 1.1规范中,307为临时重定向,注意划红线的部分,如果重定向307的原请求不是get或者head方法,那么浏览器一定不能自动的进行重定向,即便location有url,也应该忽略

也就是307继承了302在HTTP 1.0中的规范(303继承了302在HTTP 1.0中的实现)。

308

308与301定义一致,唯一的区别在于,308状态码不允许浏览器将原本为POST的请求重定向到GET请求上。


302

phpheader("location:")中,如果没有明确写明状态码的话,会默认是302跳转,也就是常说的临时跳转,在seo领域里面,302并不转移权重值。

303

HTTP 303 See Other 重定向状态码,通常作为 PUT 或 POST 操作的返回结果,它表示重定向链接指向的不是新上传的资源,而是另外一个页面,比如消息确认页面或上传进度页面。而请求重定向页面的方法要总是使用 GET。

304

304状态码,304状态码的解释时:Not Modified。这个状态码并不涉及任何的页面跳转,只是告诉浏览器,资源没有修改,使用缓存就好了,并且并不会返回任何响应主体,所以,304并不跳。

307

307跳转中,因为会转移_POST值,可以用于表单第三方表单验证,大家可以仔细体会体会。

浏览器对307状态的处理规则和302状态相同。之所以将值307引入到HTTP/1.1中,是因为,甚至在最初的消息是POST的情况下,许多浏览器依旧错误地跟随302响应中的重定向信息,浏览器应该只在接收到303状态码时才跟从POST请求的重定向信息。引入这个新状态是为了消除二义性:如果接收到303响应,则继续进行GET和POST请求的重定向;如果接收到307响应,对于GET请求的重定向,则继续进行;但对于POST请求的重定向,则不再继续下去。这是HTTP/1.1新引入的状态码。

Guess you like

Origin blog.csdn.net/qq_44829421/article/details/131908442