在做web开发中,页面跳转的方式有很多种,然而有些时候这些跳转如何用到恰到好处却很容易被忽视。
客户端触发跳转有如下几种
-
使用meta元信息
1
2
|
<!--如下表示
5
秒后跳转到url指定的链接,推荐使用这种方式-->
<meta http-equiv=
"refresh"
content=
"5;url=http://my.oschina.net/ososchina/blog"
>
|
2.使用javascript中的window.location对象
1
2
3
4
5
6
7
8
9
10
11
12
|
<!--这里的代码忽略了搜索引擎对于链接价值的转移,它会被当做
'暂时地'
重定向。-->
<script type=
"text/javascript"
>
//修改window.location.href
window.location.href =
'http://my.oschina.net/ososchina/blog'
;
//替换url,注意这种方式有时并不是有效的,需要强制reload才行
//window.location.replace('http://my.oschina.net/ososchina/blog');
//window.location.reload(true);
//修改window导航
//window.navigate ('http://my.oschina.net/ososchina/blog')
</script>;
|
补充一点:在html5中,利用新的api实现前端页面mvc的跳转也是一种不错的方式(注意:服务端不跳转),利用这种方式可以实现前端MVC开发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<script type=
"text/javascript"
>
var state = {
action :
"page"
,
title :
"HTML 5 History API simple demo"
,
url :
"yourpage"
};
history.pushState(state,
"HTML 5 History API simple demo"
, state.url);
window.onpopstate = function (e) {
switch
(e.state.action) {
case
"home"
:
document.title =
"HOME ……"
;
$.get(
"index.php"
).done(function (data) { $(
"#wrapper"
).html(data); });
break
;
case
"page"
:
document.title = e.state.title;
$.get(e.state.url).done(function (data) { $(
"#wrapper"
).html(data); });
break
;
}
}
</script>;
|
以上是客户端触发的跳转
-------------------------------------------------------------------------------------------
服务端触发的跳转的方式
-
php中使用header跳转
1
2
|
header(
'Location:http://my.oschina.net/ososchina/blog'
);
//这里的代码忽略了搜索引擎对于链接价值的转移,它会被当做'暂时地'重定向。
|
推荐使用下面的方式
1
2
|
header(
'HTTP/1.1 301 Moved Permanently'
);
//固定重定向
header(
'Location: http://my.oschina.net/ososchina/blog'
);
|
有时,设置http 响应头是非常重要的,这些可以帮助搜索引擎和浏览器“理解”请求的状态
下面提供一种发送http响应头的php函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
/**
* 发送HTTP状态
* @param integer $code 状态码
* @return void
*/
function
send_http_status(
$code
) {
static
$_status
=
array
(
// Informational 1xx
100 =>
'Continue'
,
101 =>
'Switching Protocols'
,
// Success 2xx
200 =>
'OK'
,
201 =>
'Created'
,
202 =>
'Accepted'
,
203 =>
'Non-Authoritative Information'
,
204 =>
'No Content'
,
205 =>
'Reset Content'
,
206 =>
'Partial Content'
,
// Redirection 3xx
300 =>
'Multiple Choices'
,
301 =>
'Moved Permanently'
,
302 =>
'Moved Temporarily '
,
// 1.1
303 =>
'See Other'
,
304 =>
'Not Modified'
,
305 =>
'Use Proxy'
,
// 306 is deprecated but reserved
307 =>
'Temporary Redirect'
,
// Client Error 4xx
400 =>
'Bad Request'
,
401 =>
'Unauthorized'
,
402 =>
'Payment Required'
,
403 =>
'Forbidden'
,
404 =>
'Not Found'
,
405 =>
'Method Not Allowed'
,
406 =>
'Not Acceptable'
,
407 =>
'Proxy Authentication Required'
,
408 =>
'Request Timeout'
,
409 =>
'Conflict'
,
410 =>
'Gone'
,
411 =>
'Length Required'
,
412 =>
'Precondition Failed'
,
413 =>
'Request Entity Too Large'
,
414 =>
'Request-URI Too Long'
,
415 =>
'Unsupported Media Type'
,
416 =>
'Requested Range Not Satisfiable'
,
417 =>
'Expectation Failed'
,
// Server Error 5xx
500 =>
'Internal Server Error'
,
501 =>
'Not Implemented'
,
502 =>
'Bad Gateway'
,
503 =>
'Service Unavailable'
,
504 =>
'Gateway Timeout'
,
505 =>
'HTTP Version Not Supported'
,
509 =>
'Bandwidth Limit Exceeded'
);
if
(isset(
$_status
[
$code
])) {
header(
'HTTP/1.1 '
.
$code
.
' '
.
$_status
[
$code
]);
// 确保FastCGI模式下正常
header(
'Status:'
.
$code
.
' '
.
$_status
[
$code
]);
}
}
|
然后我们来优化一下
1
2
|
send_http_status(
'301'
);
//固定重定向
header(
'Location: http://google.com/'
);
|
问题来了:这里挖掘机技术必须强,使用http响应后需要注意的是,在响应头发送之前必须没有输出流输出内容,因此,这种让人满意的方法有时并不适用;下面进行改造:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?php
// 如果之前沒有任何輸出, 就送出 Location 的導向資訊
if
(!headers_sent()) {
send_http_status(
'301'
);
//固定重定向
header(
'Location: http://my.oschina.net/ososchina/blog'
);
exit;
}
else
{
/**
*echo "<script type='text/javascript'>";
*echo "window.location.href ='http://my.oschina.net/ososchina/blog'";
*echo '</script>';
*/
//或下面的这种方式(推荐)
echo
"<meta http-equiv='Refresh' content='0;URL=http://my.oschina.net/ososchina/blog'>"
;
}
?>
|
当然有时候会出现n秒后跳转过渡页面,这个也不是很困难,但这种重定向只需默认的“临时重定向”就行,避免SEO权值转移。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<?php
/**
* URL重定向
* @param string $url 重定向的URL地址
* @param integer $time 重定向的等待时间(秒)
* @param string $msg 重定向前的提示信息
* @return void
*/
function
send_redirect(
$url
,
$time
=0,
$msg
=
''
) {
//多行URL地址支持
$url
=
str_replace
(
array
(
"\n"
,
"\r"
),
''
,
$url
);
if
(
empty
(
$msg
))
$msg
=
"系统将在{$time}秒之后自动跳转到{$url}!"
;
if
(!headers_sent()) {
// redirect
if
(0 ===
$time
) {
header(
'Location: '
.
$url
);
}
else
{
header(
"refresh:{$time};url={$url}"
);
echo
(
$msg
);
}
exit
();
}
else
{
$str
=
"<meta http-equiv='Refresh' content='{$time};URL={$url}'>"
;
if
(
$time
!= 0)
$str
.=
$msg
;
exit
(
$str
);
}
}
?>
|
--------------------------------------------------------------------------------
在页面有2个红色的词语“触发”,这里的意思是通过触发事件来进行跳转的,在http请求中(http基于tcp连接),一般是 “请求-应答”模式,但这种模式是独立于页面跳转的。
实际上页面跳转分为2中方式 :客户端跳转,客户端和服务端一起跳转
客户端跳转在目前mvc主流框架中使用较为广泛,这种跳转一般通过服务端控制(Controller)触发,如j2ee servlet中的Dispatcher和forward以及php中的include,display,客户端和服务端一起跳转一般具有强制性,这个无论前端和后端均可使用,但后端使用的一个好处是可以发送状态码,对于SEO等工作具有很多好处。