渗透第一天

浅析http状态码301、302、303、307、308区别

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

img

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

缓存(永久重定向)不缓存(临时重定向)
转GET301302、303
方法保持308307

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

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

方法保持的意思是原请求和重定向的请求是否使用相同的方法,譬如原请求是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新引入的状态码。

一些常用标签

<div>是一个通用标签,表示一个区块(division)。它没有语义,如果网页需要一个块级元素容器,又没有其他合适的标签,就可以使用这个标签。

它的最常见用途就是提供 CSS 的钩子,用来指定各种样式。所以在早期,下面层层包裹的<div>就很常见。

<div class="main">
  <div class="article">
    <div class="title">
      <h1>文章标题</h1>
    </div>
  </div>
</div>

上面代码读起来很费力,因为不带有语义。后来,HTML 5 就提出了语义标签,改进了上面的代码。

<main>
  <article>
    <header>
      <h1>文章标题</h1>
    </header>
  </article>
</main>

<div>是无语义的块级元素。下面的例子使用<div>,将图像和文字组合在一起,构成一个警告区块。

<div>
  <img src="warning.jpg" alt="警告">
  <p>小心</p>
</div>

只要样式上需要多个块级元素组合在一起,就可以使用<div>。但是,这应该是最后的措施,带有语义的块级标签(比如<article><section><aside><nav>等)始终应该优先使用,当且仅当没有其他语义元素合适时,才可以使用<div>

<span>

<span>是一个通用目的的行内标签(即不会产生换行),不带有任何语义。它通常用作 CSS 样式的钩子,如果需要对某些行内内容指定样式,就可以把它们放置在<span>

<p>这是一句<span>重要</span>的句子。</p>

上面代码中,句子里面需要强调的部分,就可以放在<span>

一、DNS 是什么?

DNS (Domain Name System 的缩写)的作用非常简单,就是根据域名查出IP地址。你可以把它想象成一本巨大的电话本。

举例来说,如果你要访问域名math.stackexchange.com,首先要通过DNS查出它的IP地址是151.101.129.69

如果你不清楚为什么一定要查出IP地址,才能进行网络通信,建议先阅读我写的《互联网协议入门》

二、查询过程

虽然只需要返回一个IP地址,但是DNS的查询过程非常复杂,分成多个步骤。

工具软件dig可以显示整个查询过程。

$ dig math.stackexchange.com

上面的命令会输出六段信息。

img

第一段是查询参数和统计。

img

第二段是查询内容。

 

img

上面结果表示,查询域名math.stackexchange.comA记录,A是address的缩写。

第三段是DNS服务器的答复。

 

img

上面结果显示,math.stackexchange.com有四个A记录,即四个IP地址。600是TTL值(Time to live 的缩写),表示缓存时间,即600秒之内不用重新查询。

第四段显示stackexchange.com的NS记录(Name Server的缩写),即哪些服务器负责管理stackexchange.com的DNS记录。

 

img

上面结果显示stackexchange.com共有四条NS记录,即四个域名服务器,向其中任一台查询就能知道math.stackexchange.com的IP地址是什么。

第五段是上面四个域名服务器的IP地址,这是随着前一段一起返回的。

 

img

第六段是DNS服务器的一些传输信息。

 

img

上面结果显示,本机的DNS服务器是192.168.1.253,查询端口是53(DNS服务器的默认端口),以及回应长度是305字节。

如果不想看到这么多内容,可以使用+short参数。

$ dig +short math.stackexchange.com
​
151.101.129.69
151.101.65.69
151.101.193.69
151.101.1.69

上面命令只返回math.stackexchange.com对应的4个IP地址(即A记录)。

三、DNS服务器

下面我们根据前面这个例子,一步步还原,本机到底怎么得到域名math.stackexchange.com的IP地址。

首先,本机一定要知道DNS服务器的IP地址,否则上不了网。通过DNS服务器,才能知道某个域名的IP地址到底是什么。

 

img

DNS服务器的IP地址,有可能是动态的,每次上网时由网关分配,这叫做DHCP机制;也有可能是事先指定的固定地址。Linux系统里面,DNS服务器的IP地址保存在/etc/resolv.conf文件。

上例的DNS服务器是192.168.1.253,这是一个内网地址。有一些公网的DNS服务器,也可以使用,其中最有名的就是Google的8.8.8.8和Level 3的4.2.2.2

本机只向自己的DNS服务器查询,dig命令有一个@参数,显示向其他DNS服务器查询的结果。

$ dig @4.2.2.2 math.stackexchange.com

上面命令指定向DNS服务器4.2.2.2查询。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值