随机机会的无关重定向使用什么HTTP响应状态代码?

时间:2018-07-28 21:19:19

标签: http redirect server http-status-codes http-redirect

我的网站有1%的随机机会将访问者重定向到this YouTube video.

服务器当前发送的是旧版本302,但我希望它具有更好的语义。

我不知道重定向是永久的还是临时的。从某种意义上说,这是永久性的,因为人们总是有1%的机会被重定向;从某种意义上说,这是暂时的,因为人们不会每次都被重定向。

当前3xx响应状态代码均不符合我网站的行为。

HTTP 3xx重定向(来源:Wikipedia)

  

301永久移动
  此请求和所有以后的请求都应定向到给定的URI。[21]

“此请求以及所有将来的请求”-不,不是所有将来的请求。

  

找到了302(以前是“临时​​移动”的)
  告诉客户端查看(浏览)另一个URL。 302已被303和307取代。这是违反该标准的行业惯例的示例。 HTTP / 1.0规范(RFC 1945)要求客户端执行临时重定向(原始描述短语为“临时移动”),[22]但是流行的浏览器使用303的功能实现了302。因此,HTTP / 1.1添加了状态码303和307来区分这两种行为。[23]但是,某些Web应用程序和框架使用302状态代码就像使用303。[24]

这令人困惑。它确实指出“ 302已被303和307所取代”,所以我想这已经过时了但仍很常用?

  

303查看其他(自HTTP / 1.1起)
  可以使用GET方法在另一个URI下找到对请求的响应。当收到响应POST(或PUT / DELETE)的响应时,客户端应假定服务器已接收到数据,并应向给定URI发出新的GET请求。[25]

“可以在另一个URI下找到对该请求的响应”-Rickroll不是对原始请求的响应。它与我的网站无关! “当收到响应POST(或PUT / DELETE)的响应时,客户端应假定服务器已接收到数据,并应向给定URI发出新的GET请求。” 303说明的最后一句话不适用于我的重定向。

  

307临时重定向(自HTTP / 1.1起)
  在这种情况下,应使用另一个URI重复该请求;但是,将来的请求仍应使用原始URI。与历史上实现302的方式相反,在重新发出原始请求时不允许更改请求方法。例如,应该使用另一个POST请求重复POST请求。[30]

“在这种情况下,应使用另一个URI重复该请求;但是,以后的请求仍应使用原始URI。”是!这就是我的重定向。 “ ...重新发出原始请求时,不允许更改请求方法。例如,应使用另一个POST请求重复POST请求。不幸的是,这不适用于我的重定向。即使用户提交表单(POST方法),我的网站也会随机对用户进行Rickroll。

  

308永久重定向(RFC 7538)
  该请求和所有以后的请求应使用另一个URI重复。 307和308与302和301的行为并行,但不允许HTTP方法更改。因此,例如,向永久重定向的资源提交表单可能会继续顺利进行。[31]

308与301存在相同的问题,因为并非将来所有请求都应发送到Rickroll视频。此外,不允许更改方法。

我的服务器应该发送什么HTTP响应状态代码来进行与我的实际站点无关的随机机会重定向?

1 个答案:

答案 0 :(得分:11)

HTTP响应状态代码的正式来源是RFC7231,而不是Wikipedia。 您应该仔细阅读RFC7231 Section 6.4来解释3XX状态代码。

“通过随机机会重定向访问者”与实际的重定向无关, 因此,符合您要求的状态代码为303, Section 6.4.4中的解释如下(强调我的意思):

  

303(请参阅其他)状态代码表示服务器处于   将用户代理重定向到其他资源,如   位置标头字段中的URI,旨在提供一个   间接响应原始请求。用户代理可以执行   针对该URI的检索请求(如果是GET或HEAD请求,   使用HTTP),也可以将其重定向,并显示最终   结果作为对原始请求的答复。请注意,新的URI   位置标头字段中的不等同于   有效的请求URI。

303符合您的要求的三个原因:

  1. “到其他资源”:访问者被重定向到的资源与他们最初请求的资源不同。
  2. “执行检索请求”:使用GET或HEAD请求获取最终资源。
  3. “不视为等效”:原始请求URI不能替换为新URI,因为它不等效,换句话说,它是临时的。

为什么不是302? 由于Section 6.4.3(重点是我的)中的这一部分解释:

  

由于历史原因,用户代理可以更改请求   方法(从POST到GET)用于后续请求。

换句话说,用户代理可以使用相同的请求方法或不同的请求方法。 规格允许302的灵活性不符合您的要求。