重定向原理
在 HTTP 协议中,重定向操作由服务器通过发送特殊的响应(即 redirects)而触发。HTTP 协议的重定向响应的状态码为 3xx 。浏览器在接收到重定向响应的时候,会采用该响应提供的新的 URL ,并立即进行加载。大多数情况下,除了会有一小部分性能损失之外,重定向操作对于用户来说是不可见的。
下面是HTTP重定向的工作过程
在a中,Alice向www.joes-hardware.com发送了一条请求
GET /hammers.html HTTP/1.0
Host: www.joes-hardware.com
User-Agent: Mozilla/4.51 [en] (X11UIRIX 6.2 IP22)
在b中,服务器没有回送带有HTTP状态码200的Web页面主体,而是回送了一个带有HTTP状态码302的重定向报文(Location指明了新的访问地址)
HTTP/1.0 302 Redirect
Server: Stronghold/2.4.2 Apache/1.3.6
Location: http://161.58.228.45/hammers.html
现在,在c中,浏览器会用重定向URL重新发送请求,这次会发送给主机161.58.228.45。
GET /hammers.html HTTP/1.0
Host: 161.58.228.45
User-Agent: Mozilla/4.51 [en] (X11UIRIX 6.2 IP22)
重定向映射可以划分为三个类别:永久重定向、临时重定向和特殊重定向。永久性重定向操作是永久性的。它表示原 URL 不应再被使用,而应该优先选用新的 URL。搜索引擎机器人会在遇到该状态码时触发更新操作,在其索引库中修改与该资源相关的 URL ,这种情景服务器的返回状态码为301 moved permanently。有时候请求的资源无法从其标准地址访问,但是却可以从另外的地方访问。在这种情况下可以使用临时重定向。搜索引擎不会记录该新的、临时的链接,这种情景服务器返回的状态码为302 Found。还有一种特殊的重定向,服务器返回304 not modified,告诉客户端资源未被修改,可以使用本地缓存的资源。
重定向机制的实现
重定向的实现有3种方式,
第一种,即HTTP 协议中重定向机制是应该优先采用的创建重定向映射的方式,这需要Web 开发者对于服务器有控制权,或能对其进行配置。如在apache下重定向映射可以在服务器的配置文件中设置。mod_alias 模块提供了 Redirect 和 Redirect_Match 两种指令来设置 302 响应(默认值):
<VirtualHost *:80>
ServerName example.com
Redirect / http://www.example.com
</VirtualHost>
URL http://example.com/ 会被重定向至 http://www.example.com/。
第二种是HTML重定向机制,Web 开发者可以在精心制作的 HTML 页面的 <head> 部分添加一个 <meta>元素,并将其 http-equiv 属性的值设置为 refresh 。当显示页面的时候,浏览器会检测该元素,然后跳转到指定的页面。
<head>
<meta http-equiv="refresh" content="0URL=http://www.example.com/" />
</head>
content 属性的值开头是一个数字,指示浏览器在等待该数字表示的秒数之后再进行跳转。建议始终将其设置为 0 来获取更好的可访问性。该方法仅适用于 HTML 页面(或类似的页面),然而并不能应用于图片或者其他类型的内容。
在 JavaScript 中,重定向机制的原理是设置 window.location 的属性值,然后加载新的页面。
window.location = "http://www.example.com/"
与 HTML 重定向机制类似,这种方式并不适用于所有类型的资源,并且显然只有在支持 JavaScript 的客户端上才能使用。另外一方面,它也提供了更多的可能性,比如在只有满足了特定的条件的情况下才可以触发重定向机制的场景。
应用场景
HTTP重定向可以在服务器间导引请求,但它有以下几个缺点:需要原始服务器进行大量处理来判断要重定向到哪台服务器上去。有时,发布重定向所需的处理量几乎与提供页面本身所需的处理量一样;增加了用户时延,因为访问页面时要进行两次往返;如果重定向服务器出故障,站点就会瘫痪。
常见的应用场景有,
有些Web站点会将HTTP重定向作为一种简单的负载均衡形式来使用。处理重定向的服务器(重定向服务器)找到可用的负载最小的内容服务器,并将浏览器重定向到那台服务器上去。
域名别称,理想情况下,一项资源只有一个访问位置,也就是只有一个 URL 。但是由于种种原因,需要为资源设定不同的名称(即不同的域名,例如带有和不带有 www 前缀的URL,以及简短易记的 URL 等)。在这种情况下,实用的方法是将其重定向到那个实际的(标准的)URL,而不是复制资源。
在以下几种情况下可以使用域名别称:
扩大站点的用户覆盖面。一个常见的场景是,假如站点位于 www.example.com 域名下,那么通过 example.com 也应该可以访问到。这种情况下,可以建立从 example.com 的页面到 www.example.com 的重定向映射。此外还可以提供常见的同义词,或者该域名容易导致的拼写错误的域名别称。
迁移到另外一个域名。例如,公司改名后,你希望用户在搜索旧名称的时候,依然可以访问到应用了新名称的站点。
强制使用 HTTPS 协议。对于 HTTP 版本站点的请求会被重定向至采用了 HTTPS 协议的版本。如
保持链接有效,当你重构 Web 站点的时候,资源的 URL 会发生改变。即便是你可以更新站点内部的链接来适应新的命名体系,但无法控制被外部资源使用的 URL 。你并不想因此而使旧链接失效,因为它们会为你带来宝贵的用户(并且帮助优化你的SEO),所以需要建立从旧链接到新链接的重定向映射。
不安全请求的临时响应,不安全( Unsafe )请求会修改服务器端的状态,应该避免用户无意的重复操作。一般地,你并不想要你的用户重复发送 PUT 、 POST 或 DELETE 请求。假如你仅仅为该类请求返回响应的话,简单地点击刷新按钮就会(可能会有一个确认信息)导致请求的重复发送。在这种情况下,服务器可以返回一个 303 (See Other) 响应,其中含有合适的响应信息,或处理成功后 redirect 到另一个 jsp/php页面。即如果刷新按钮被点击的话,只会导致该页面被刷新,而不会重复提交不安全的请求。
文章封面:
王者荣耀元歌 —— 是我?不是我!是傀儡!
nginx重定向规则(apache 的简介);
nginx两种跳转:显式跳转,隐式跳转;
伪静态;
同源策略;
1: zouzhenzhong.com 定向到 https://www.zouzhenzhong.com ,给网站加小绿锁;便于百度的收录,权重集中到一个域名;
2: tec.zouzhenzhong.com 隐式到 https://www.zouzhenzhong.com/article/listshow?menu_id=101 ,看上去我有个专业的技术博客。
一个字就是干!下面贴出nginx 配置 zouzhenzhong.com 和 tec.zouzhenzhong.com 的源文件。(个人网站被攻击也没啥损失,自己印象云,git都有备份,还请大哥高抬贵手!)
zouzhenzhong.conf
#主站
server {
#这里是ssl 对应配置,从对应的云服务器copy demo对应填写即可
listen 443 ssl
server_name www.zouzhenzhong.com
ssl on
ssl_certificate /etc/ssl/tencent/ www.zouzhenzhong.com/1_www.zouzhenzhong.com_bundle.crt
ssl_certificate_key /etc/ssl/tencent/ www.zouzhenzhong.com/2_www.zouzhenzhong.com.key
ssl_session_timeout 5m
ssl_protocols TLSv1 TLSv1.1 TLSv1.2#按照这个协议配置
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE#按照这个套件配置
ssl_prefer_server_ciphers on
# www.zouzhenzhong.com 站点的数据能够让其他任何网站拉取,展示;担心安全问题可以使用jsonp,数据源带token的形式。
add_header Access-Control-Allow-Origin *
#url 隐式跳转: https://www.zouzhenzhong.com/121.html 显示的是 https://www.zouzhenzhong.com/article/detail/121 的内容, 但是url 显示的是 https://www.zouzhenzhong.com/121.html
#注意关键词proxy_pass
location ~* \.html$ {
rewrite ^/([\d]+)\.html$ /article/detail/$1 break
proxy_pass https://www.zouzhenzhong.com
}
location / {
root /home/yiiblog/frontend/web
index index.html index.php
if (!-e $request_filename){
rewrite ^/(.*) /index.php last
}
}
#没有下面 cgi(Common Gateway Interface)将无法解析php
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000
fastcgi_index index.php
root /home/yiiblog/frontend/web
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name
include fastcgi_params
}
#对应资源,不区分大小写,301强跳,便于cdn
location ~* \.(png|jpg|jpeg||gif|js|css|woff2|eot|ttf|woff|svg|otf)$ {
rewrite ^/(.*)$ https://staticblog.zouzhenzhong.com/$1 permanent
}
}
server {
#注意https 监听的一定是443端口所以 zouzhenzhong.com 监听了 80端口和443两个端口;
listen 80 default_server
server_name zouzhenzhong.com
#重定向到www
rewrite ^/(.*)$ https://www.zouzhenzhong.com/$1 permanent
}
tec_zouzhenzhong.conf
server {
listen 443
server_name tec.zouzhenzhong.com
ssl on
ssl_certificate /etc/letsencrypt/live/ zouzhenzhong.com/tec_zouzhenzhong/1_tec.zouzhenzhong.com_bundle.crt
ssl_certificate_key /etc/letsencrypt/live/ zouzhenzhong.com/tec_zouzhenzhong/2_tec.zouzhenzhong.com.key
ssl_session_timeout 5m
ssl_protocols TLSv1 TLSv1.1 TLSv1.2#按照这个协议配置
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE#按照这个套件配置
ssl_prefer_server_ciphers on
# tec.zouzhenzhong.com 所有的访问 都会隐式重定向到 https://www.zouzhenzhong.com 代理的/article/listshow?menu_id=101
location / {
rewrite ^/(.*)$ /article/listshow?menu_id=101 break
proxy_pass https://www.zouzhenzhong.com
}
#location ~ .php$ 没有做cgi的配置, tec.zouzhenzhong.com 并不需要解析php
}
server {
listen 80#这个不能省略啊
server_name tec.zouzhenzhong.com
rewrite ^(.*)$ https://${server_name}$1 permanent
}
nginx重定向规则
^/([\d]+)\.html$/article/detail/$1
^/ 就理解为开始就好(还有很多形式,就这样用就行)。
使用括号 () 通过正则匹配标记要截取的内容 ,对应成变量$1,$2...
location匹配 location / 通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中的default。
参考资料: nginx 参数 从定向demo
nginx两种跳转
显式跳转:访问的url跳转
location ~* \.(png|jpg|jpeg||gif|js|css|woff2|eot|ttf|woff|svg|otf)$ {
rewrite ^/(.*)$ https://staticblog.zouzhenzhong.com/$1 permanent
}
隐式跳转:访问的url 不跳,但是内容已经跳了。
location ~* \.html$ {
rewrite ^/([\d]+)\.html$ /article/detail/$1 break
proxy_pass https://www.zouzhenzhong.com
}
注意: service nginx restart 前进行 nginx -t 检查;配置文件记得备份;
伪静态
伪静态 :优点:便于seo 缺点:会增加一点CPU开销(多一次跳转)优点的作用 >缺点。
同源策略
对应的service name 对那些host开放;比如: www.zouzhenzhong.com Access-Control-Allow-Origin * , www.zouzhenzhong.com 可以给其他网站加载,嵌套渲染等;
apache 重定向
kimma.conf : www.viyoya.com 中 静态文件跳 kimma.viyoya.com
<VirtualHost *:80>
ServerAdmin kimma.viyoya.com
DocumentRoot /var/www/html
Header set Access-Control-Allow-Origin “*”
<ifModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} www.viyoya.com .*$ [NC]
RewriteRule "^/(.*)\.(png|jpg|ttf|woff|woff2|jpeg|GIF|gif|js|css|woff2|eot|ttf|woff|svg|otf|txt)$" " http://kimma.viyoya.com/ $1.$2 " [L,R=301]
</ifModule>
</VirtualHost>
apache .htaccess viyoya.com 跳 www.viyoya.com
RewriteEngine On
RewriteCond %{HTTP_HOST} ^ viyoya.com [NC]
RewriteRule ^/(.)*$ http://www.viyoya.com/$1 [L,R=301]
Header set Cache-Control "max-age=2592000"
注意:重启apche: apachectl restart 前检查 apche: apachectl -t
文章来源 : 邹振忠的博客 - 重定向漫谈
301跳转通常用在网站换域名和为了保持链接统一性所用的。比如原来的域名www.a.com现在换成www.b.com,用了301跳转后,访问www.a.com/about.html就会自动变成www.b.com/about.html。下面摘抄一下设置301的代码:301跳转代码全集(ASP|PHP|JSP|.NET):IIS下301设置:
Internet信息服务管理器 ->虚拟目录 ->重定向到URL,输入需要转向的目标URL,并选择“资源的永久重定向”。
ASP下的301转向代码
<%@ Language=VBScript %>
<%
Response.Status=”301 Moved Permanently”
Response.AddHeader “Location”, “http://www.boaer.com/”
%>
ASP.Net下的301转向代码
<script runat=”server”>
private void Page_Load(object sender, System.EventArgs e)
{
Response.Status = “301 Moved Permanently”
Response.AddHeader(”Location”,”http://www.boaer.com/”)
}
</script>
PHP下的301转向代码
header(”HTTP/1.1 301 Moved Permanently”)
header(”Location: http://www.boaer.com/”)
exit()
CGI Perl下的301转向代码
$q = new CGI
print $q->redirect(”http://www.boaer.com/”)
JSP下的301转向代码
<%
response.setStatus(301)
response.setHeader( “Location”,“http://www.boaer.com/” )
response.setHeader( “Connection”,“close” )
%>
Apache下vhosts.conf中配置301转向,为实现URL规范化,SEO通常将不带WWW的域名转向到带WWW域名,vhosts.conf中配置为:
<VirtualHost *:80>
ServerName www.boaer.com
DocumentRoot
</VirtualHost>
<VirtualHost *:80>
ServerName xxx.com
RedirectMatch permanent ^/(.*) http://www.boaer.com/$1
</VirtualHost>
Apache下301转向代码,新建.htaccess文件,输入下列内容(需要开启mod_rewrite):1)将不带WWW的域名转向到带WWW的域名下:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^xxx.com [NC]
RewriteRule ^(.*)$ http://www.boaer.com/$1 [L,R=301]
2)重定向到新域名
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^(.*)$ http://www.boaer.com/$1 [L,R=301]
3)使用正则进行301转向,实现伪静态
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^news-(.+)\.html$ news.php?id=$1
将news.php?id=123这样的地址转向到news-123.html
301设置好这后,就要检测一下301是否生效。这里有两个在线检测301重定向的工具:
国内版:http://tool.chinaz.com/pagestatus/
国外版:http://www.seoconsultants.com/tools/headers#Results
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)