什么是客户端重定向和服务器重定向,它们之间有什么区别?
众所周知,我们当今的互联网是基于TCP/IP的客户机服务器模式。那么这就引申出了两种重定向方式:客户端重定向和服务器重定向。
这两个概念很好理解,在客户端实现的重定向就叫客户端重定向,在服务器端实现的重定向就叫服务器重定向(听起来是不是很废话,我也觉得)
那么该到底如何区分呢?
在客户端
先说客户端重定向吧,它有个专门的名字叫Client Redirect。
它的实现通常是基于JavaScript来调用某些浏览器API来实现的重定向。由于它依赖前端API,因此它可以说是一种很主动的重定向方式。对于curl和wget这类的请求器来说,它获取到的实质仍然还是200响应和一个正常的html页面信息。只不过对于客户端而言它在得到响应后瞬间执行了里面的跳转指令来改变当前目标罢了。所以这种重定向方式非常适用于纯静态网站的技术栈,或者说是这类技术唯一能实现的重定向方式。同时它对于点击按钮或者等待时间之类的纯前端交互的跳转来说非常适用。
例如它的不同类型的调用:
1 | // 普通跳转(保留历史记录,可后退) |
当然,也有不依赖于JS的版本:
1 | <meta http-equiv="refresh" content="5; url=https://example.com/"> |
它表示在5秒后刷新并重定向到新的https://example.com/ 网址。(在某些浏览器中,meta refresh 会影响浏览器的“后退”按钮功能。)
虽然它实现起来简单,但是它所带来的弊端也非常明显:假如你的用户关闭了JavaScript能力,同时页面上如果没其他内容的话就会无法重定向。同时对于不执行JavaScript和html的非浏览器客户端来说,它们看到的只是一串代码文本而已,并不会造成实质性的跳转。
在服务器
而服务器重定向更高级,是相比前端重定向而言更根本更彻底的被动重定向方案:因为它在绝对意义上“宣布”了这个url的类型就是重定向,以及重定向到了哪,类型是什么。所以它是根本意义上的、权威的重定向方案,同时也是最标准最彻底的重定向方式,任何HTTP客户端都要服从这个重定向命令并作出跟随。它也有个专门的称呼叫HTTP重定向(http redirect)。
它典型的特征是不再使用200响应,而是会转为重定向专用的标准响应码。比如说经典的有30x系列的响应码,它告诉浏览器这个重定向是何种类型的重定向,解决了客户端重定向无法标识类型的问题(毕竟客户端重定向始终都是以200来响应嘛)
服务器重定向更高级的一点是,它通过指定Location响应头来提供重定向目标,这意味着它还能同时提供响应体。比如说B站,有些重定向同时返回了带有“Found”文本的超链接以提供给因为各种原因未能自动重定向的情况来降级为通过页面手动点击跳转。
一个典型的服务器级重定向的响应应该包括:
(以B站短链接https://b23.tv/YOzfS7w为例,值得一提的是b23.tv短链接有效期后面被B站给改成1年了)
它的标志是302响应码和代表了重定向目标的Location响应头部。
当然,既然是任何HTTP客户端都需要跟随,那么它对于搜索引擎蜘蛛来说同样有效。假如你需要更换域名,同时旧的还没过期。怎么才能让搜到的用户无缝地切换到你的新站呢?答案是服务器重定向。你可以通过指定响应码为301来表示当前资源已经永久地转移到了新的地址,这样搜索引擎就能更好地去转移权重了。同样的,这也是现代短链接的标准和主流的实现方式。
常见的重定向状态码:
- 301 Moved Permanently: 永久重定向。资源已永久移动到新URL,搜索引擎会将权重和排名转移到新地址。
- 302 Found / 307 Temporary Redirect: 临时重定向。资源临时从另一个URI响应请求。对于SEO,搜索引擎通常会抓取新内容,但保留原地址的权重。
它拥有了良好的性能,因为它由浏览器直接处理跳转,无需加载整个中间页面。所以简单来说它比静态版的前端JavaScript重定向来的更有效率。
需要甄别的误区
在编写服务器端动态API或者网页时,常常会有这样的需求:假如说你有个/api/qunzhu/robot/的接口在本地路径,同时又想对外访问的链接的路径是/qunzhu/hacker/。我们会编写自定义路由策略映射来解决这个问题是吧?可能会有人认为它也是重定向,这样想是不对的。因为它仅仅只发生在了服务器,客户端并没有出现访问后改变目标的情况。也就说重定向这个行为是相对于客户端而言的,只发生在了服务器的不叫真正意义上的重定向。它也有专门的名字叫**URL重写(URL Rewriting)**或者也可以直接叫做路由(Routing),它是建立在服务器内部的一套映射关系,实现对外保持统一的URL。
于是最终重定向的定义是:一般情况下,发生在客户端上的,具有由原始链接改变到目标链接并重新发起新请求的就叫做重定向。客户端会为最终的目标资源发起一次新的、独立的HTTP请求。无论是服务器返回指令,还是客户端自行执行脚本,只要满足这个条件,就发生了重定向。






