重定向用于将用户从一个URL从新路由到另外一个URL。重定向有不少种——301和302是最经常使用的两种。重定向可能有不少不一样的缘由,包括网站从新设计、跟踪流量、记录广告点击和创建易于记忆的URL。javascript
当web服务器向浏览器返回一个重定向时,响应中就会拥有一个范围在3xx的状态码。这表示用户代理必须执行进一步操做才能完成请求。
300 Multiple Choices(基于Content-Type)
301 Moved Permancently
302 Moved Temporarily(亦称Found)
303 See Other(对302的说明)
304 Not Modified
305 Use Proxy
306 (已废弃)
307 Temporary Redirect (对302的说明)html
"304 Not Modified"并不真的是重定向——它用来响应条件GET请求,避免下载已经存在于流量器缓存中的数据java
301和302是使用得最多的。状态码303和307是在http1.1规范中添加的,用来澄清对302的使用(滥用),可是几乎没有人用303和307,绝大多数网站仍然在沿用302.web
下面是一个301响应头的一个示例
浏览器会自动将用户带到Location字段所给出的URL。重定向所必需的全部信息都出如今这个头中了。响应体一般是空的。无论叫什么名字,301和302响应在实际中都不会被缓存,除非有附加的头——如Expires或Cache-Control等——要求它这么作。apache
还有其余方法能够自动将用户重定向到其余URL。HTML文档的头中包含的meta refresh标签能够在其content属性所指定的秒数以后重定向用户编程
<meta http-equiv="refresh" content="0; url=http://strbesouders.com/newuri">
javascript也能够用于执行重定向,将document.location设置为指望的url便可。若是你必须进行重定向,最好的技术是使用标准的3xx HTTP状态码,这主要是为了确保后退按钮可以正确工做。后端
不少web开发人员没有意识到,在url的结尾必须出现斜线(/)而没出现时,如http://astrology.yahoo.com/as... 包含了一个到http://astrology.yahoo.com/as... 的重定向。当缺乏结尾的斜线时发送重定向有着很充分的理由——它容许自动索引(autoindexing,自动转到默认的index.html上)而且可以得到与当前目录相关的url(如logo.gif)。然而,不少流行的web页面并不依赖自动索引,而是依赖特定的url和处理器。另外,url一般也与根目录相关而不是和当前目录相关。浏览器
注意当主机名后缺乏结尾斜线时不会发生重定向。例如,http://www.yahoo.com 不会产生重定向。然而,你在浏览器中看到的最终的url是包含结尾斜线的——http://www.yahoo.com/ .致使自动产生结尾斜线的缘由是,浏览器在运行get请求时必需指定一些路径。若是没有路径,例如http://www.yahoo.com 它就会简单地使用文档根(/)
GET / HTTP 1.1
当缺乏结尾斜线时发送重定向是不少web服务器的默认行为,包括Apache. Alias指令是一种简单的方法。另外一种选择是使用mod_rewrite模块,但Alias更加简单。(注1)Astrology网站的问题能够经过向Apache配置中添加下列内容来解决——
Alias /astrology /user/local/apache/htdocs/astrology/astrology.html缓存
若是使用Apache2.0中的处理器,一种更为清晰的解决方案是使用DirectorySlash指令。假设有一个名为astrologyhandler的处理器,能够像下面这样使用DirectorySlash安全
<Localtion /astrology> DirectorySlash Off SetHandler astrologyhandler </Localtion>
这些方法都不能解决查找与当期目录相关的url问题,所以页面中组件的url必须与根目录相关。并且,你还必须知道各模块运行的顺序(尤为是mod_dir和mod_autoindex),由于这样使用DirectorySlash可能会有安全隐患。
总之,若是你的网站包含目录并使用了自动索引,用户就必须忍受一个到达预期页面的重定向。检查一下你的web日志就能看到发出了多少301状态,这能帮助你认识到多么值得去解决缺乏结尾斜线的问题。
想象一下网站后端被重写的情形。这常常发生,新的实现中的url极可能会有所不一样。将用户从旧的url转移到新的url的最简单的方式就是重定向。重定向是使用定义良好的API——url来整合两个代码基础的一种方式。
将旧网站链接到新网站只是重定向这种常见应用中的表现形式之一。其余形式还包括将一个网站的不一样部分链接起来,以及基于一些条件(浏览器类型、用户帐户类型等)来引导用户。使用重定向来链接两个网站很简单并且只须要不多的额外代码。
其实整合后端还有其余的选择,但比重定向须要更多的开发工做,不过这样不会损害用户体验。
1.Alias、mod_rewrite和DirectorySlash要求除url以外还要提交到一个接口(处理器或文件名),但易于实现。
2.若是两个后端位于同一台服务器,则它们的代码极可能本身就能链接。例如,旧的处理器代码能够经过编程调用新的处理器代码。
3.若是域名变了,可使用一个CNAME(一条DNS记录,用于建立从一个域名指向另外一个域名的别名)让两个主机名指向相同的服务器。若是能作到这一点,这里提到的技术(Alias、mod_rewrite、DirectorySlash和直接链接代码)就是可行的。
重定向常常用于跟踪用户流量的流向。例如,sports连接的url是http://www.yahoo.com/r/26.单...,其Location被设置为http://sports.yahoo.com/。经过分析来自www.yahoo.com的web服务器日志能够得知人们离开Yahoo!的首页后的流量去向。
另外一种选择是使用Referer日志来跟踪流量去向。每一个http请求都包含一个url,代表从哪一个页面发起的请求,也就是引用方(有的时候没有引用页,当用户键入url或使用书签时)。在这里,当用户从Yahoo!主页导航到Sports页时,sports.yahoo.com的访问日志中会包含一个Referer,其值为http://www/yahoo.com/。
出站流量使用referer就不太现实了
Yahoo!search目前将每一个搜索结果连接包装到一个重定向中来解决跟踪的问题。搜索结果的url都指向rds.yahoo.com并将最终的目标看成参数包含在该url中。例如,下面是指向wikipedia的“Performance”词条的搜索结果连接
http://rds.yahoo.com/[...]5742/**http%3a/en.wikipedia.org/wiki/Performance
单击这个搜索结果会访问rds.yahoo.com,它将返回一个302响应,其Location被设置为http://en.wikipedia.org/wiki/...**参数就能跟踪用户去了哪里。这个重定向使得获取目标页面变慢了。
除了重定向,还能够选择信标——一个http请求,其url中包含有跟踪信息。跟踪信息能够从信标web服务器的访问日志中提取出来。信标响应一般是一个1px*1px的透明图片;不过204响应更为优秀,由于它更小,历来不会被缓存,并且绝对不会改变浏览器状态。
在Yahoo!search,目标是不管什么时候用户单击搜索结果连接时都要发送一个信标。这经过为每一个链接提供onClick处理器来完成(当启用了javascript时)。onclick处理器将调用一个函数,请求一个图片,并在图片的url中包含要跟踪的信息。
这种状况下,挑战是发送信标和页面自身被卸载之间的竞态情形。图片信标的onload处理器能够用于确保在卸载文档以前信标应传送完毕。
这种方法可能和使用重定向同样慢,另外一种方式是使用XMLHttpRequest来发送信标,但在卸载页面以前只需等请求到达readyState 2便可。这比等待重定向的整个http响应要快,但你必须决定是否有必要采起这么复杂的方式。
使用重定向的另外一种动机是使url更加美观而且易于记忆。如http://www.google.com/tools/f... -> http://www.google.com.
可是,使用alias、mod_rewrite、DirectorySlash和直接连接代码来避免重定向也能达到目的。