Ajax 简介:
AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。
AJAX = 异步 JavaScript和XML(标准通用标记语言的子集)。
AJAX 是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个网页页面。
存在问题
如果使用Firefox等浏览器访问RMS网站时,我们可能会发现页面之间的切换是通过AJAX异步请求实现的,同时页面的URL不会发生改变,虽然可以通过页面上的按钮通过AJAX异步请求实现回退刷新,但是对于浏览器前进和后退不能支持,每当刷新与后退之后,页面都会退到最开始的欢迎页面。AJAX可以实现页面的局部刷新,可以做到非常好的数据加载效果,给用户带来非常良好的体验,但是AJAX不能在浏览器的历史会话中保留记录,当你点开一个页面,AJAX各种数据加载非常快捷,例如一个列表页面可以用异步加载来翻页,但是如果用户一不小心刷新了页面,那么页码就得重新开始计算,一旦用户改变了会话状态(浏览器的前进、后退、刷新),那么AJAX就会丢失相关的数据。
传统的AJAX存在如下的问题:
1、可以无刷新改变页面内容,但无法改变页面URL
2、不能支持通过网址直接访问系统某一模块,必须进过点按操作
3、回退、刷新必须开发人员自己第一,既给开发人员增加了工作量,又不符合用户习惯
4、进而浏览器引入了onhashchange的接口,不支持的浏览器只能定时去判断hash是否改变
5、但这种方式对搜索引擎很不友好
使用技术
为了解决传统ajax带来的问题,HTML5里引入了新的API,即:history.pushState,history.replaceState
可以通过pushState和replaceState接口操作浏览器历史,并且改变当前页面的URL。
pushState是将指定的URL添加到浏览器历史里,replaceState是将指定的URL替换当前的URL。
1
|
history.pushState(state, title, url)
|
将当前URL和history.state加入到history中,并把新的state和URL添加到当前。不会造成页面刷新。
state:与要跳转到的URL对应的状态信息。
title:标题(现在是被忽略,未作处理)。
url:要跳转到的URL地址,不能跨域。
1
|
history.replaceState(state, title, url)
|
history.replaceState()操作类似于history.pushState(),不同之处在于replaceState()方法会修改当前历史记录条目而并非创建新的条目。
state:与要跳转到的URL对应的状态信息。
title:标题(现在是被忽略,未作处理)。
url:要跳转到的URL地址,不能跨域。
addEventListener(type, listener)
addEventListener是一个侦听事件并处理相应的函数。
type:事件的类型。
listener:侦听到事件后处理事件的函数。此函数必须接受 Event对象作为其唯一的参数,并且不能返回任何结果。
解决方法
由于AJAX无刷新改变页面内容的,所以页面的URL始终是不变的,为了区分页面上的各个不同内容,首先需要重新定义一下各个页面的URL,因为RMS网站多使用$.post异步请求,我们可以用URL记录post请求的各个参数(请求地址、传递参数),当浏览器进行刷新、回退操作时,根据URL记录的信息自动发送post请求,进入对应页面,从而实现希望的功能。
定义URL语法:
已如下地址为例:
“http://localhost/rms_hold/index.php/Home/Index/loadHomePage#/rms_hold/index.php/Home/ResourceRequest/getRequestPage@apply_type=1&resource_name=ADM_BIZCARD!1”
“http://localhost/rms_hold/index.php/Home/Index/loadHomePage”是原先页面的URL,如果在问题解决之前在RMS网站上进行任何点按操作,网址一直不会有任何变动。现在我们使用“#”分割网址,“#”之后就是我们所记录的ajax请求“/rms_hold/index.php/Home/ResourceRequest/getRequestPage”是请求的地址,它由“#”与“@”分割,而在“@”与“!”之间的这是发向请求地址的各个参数,“apply_type=1”与“resource_name=ADM_BIZCARD”由“&”进行分割。
刷新、回退监听处理:
1
2
3
4
5
6
7
8
9
10
11
|
if
(history.pushState) {
window.addEventListener(
"popstate"
,
function
() {
back_ajax_mod_url();
back_ajax_post();
if
(location.href.indexOf(
"#"
)==-1){
window.location.reload();
}
});
back_ajax_mod_url();
back_ajax_post();
}
|
如以上代码所示,window对象上提供了onpopstate事件,可以使用addEventListener方法监听onpopstate事件,每当URL因为浏览器回退时都会对得到的URL在back_ajax_mod_url()与back_ajax_post()函数中进行解析、处理,而当浏览器刷新时,根据history.pushState的返回值不空,依然会对得到的URL在back_ajax_mod_url()与back_ajax_post()函数中进行解析、处理。
对外接口:
1
2
3
4
5
6
7
|
function
back_ajax_mod_url(){
var
url_ajax=ajaxback_url.pop();
var
title =
"Home | UniqueSoft RMS"
;
if
(url_ajax){
history.pushState({ title: title }, title,location.href.split(
"#"
)[0] +
"#"
+ url_ajax);
}
}
|
介绍一下back_ajax_mod_url()函数,它与数组ajaxback_url组成对外接口,ajaxback_url是一个全局数组,用来存放需要加入到history中的URL,然后由back_ajax_mod_url()函数在无页面刷新的情况下将当前URL和history.state加入到history中。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$(
"#reportTable tbody"
).on(
"click"
,
"trtd img[alt = 'Detail']"
,
function
() {
var
id = $(
this
).attr(
"business_leave_id"
);
$.post(
"__MODULE__/ReportCenter/getReportDetailPage"
,{
"report_name"
:
"ADM_TRAVEL_REP"
,
"item_id"
: id,
},
function
(data) {
ajaxback_url.push(
"__MODULE__/ReportCenter/getReportDetailPage"
+
"@"
+
"item_id="
+ id +
"&"
+
"report_name=ADM_TRAVEL_REP"
);
$(
"#container"
).html(data);
back_ajax_mod_url();
});
});
|
以上函数是RMS系统里的一个AJAX异步请求事件,会造成页面无刷新变化,加粗部分就是我们提供的对外接口,使用该接口后在history中会产生一条新的URL用来记录达到该页面的post方法。
URL解析处理器:
如下面函数所示back_ajax_post()为RMS系统的URL解析处理器,根据之前提到的URL语法,读出页面上改变内容的AJAX请求,并且自动发送AJAX请求,获取需要的页面
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
62
63
64
65
66
|
function
back_ajax_post() {
if
(location.href.indexOf(
"#"
)!= -1) {
var
post_href =location.href.split(
"#"
)[1];
if
(location.href.indexOf(
"@"
)!= -1) {
var
post_url =post_href.split(
"@"
)[0];
var
post_params =post_href.split(
"@"
)[1];
if
(post_params.indexOf(
"!"
) != -1) {
var
post_page_index =post_params.split(
"!"
)[1];
post_params =post_params.split(
"!"
)[0];
};
}
else
{
var
post_url = post_href;
var
post_params =
""
;
var
post_page_index =
""
;
}
var
get_resource_href =location.href;
if
(get_resource_href.indexOf(
"!"
) != -1) {
get_resource_href =get_resource_href.split(
"!"
)[0];
};
if
(get_resource_href.indexOf(
"resource_name="
) != -1) {
var
has_resource_name =get_resource_href.split(
"resource_name="
)[1];
var
siderbar_index =has_resource_name;
}
else
if
(get_resource_href.indexOf(
"report_name="
) != -1) {
var
has_resource_name =get_resource_href.split(
"report_name="
)[1];
var
siderbar_index =has_resource_name.split(
"_REP"
)[0];
};
if
(!post_page_index ||$(
"#personalInfo"
).length <= 0) {
if
(!post_url) {
window.location.href =
"__MODULE__"
;
}
$.ajax({
type:
"post"
,
url: post_url,
data: post_params,
success:
function
(res){
$(
'#pageContainer'
).html(res);
if
(post_page_index) {
location.href= location.href.split(
"!"
)[0] +
"!1"
;
}
else
{
location.href= location.href.split(
"!"
)[0];
};
},
error:
function
(res) {
window.location.href =
"__MODULE__"
;
},
});
}
//for request page next&back
if
(post_page_index) {
var
previous_index =$(
".navbar,.steps .navbar-innerul.row-fluid"
).find(
"li.active"
).find(
".number"
).text();
var
differ =post_page_index - previous_index;
lock_for_req_back_next =1;
if
(differ > 0) {
for
(
var
i = 0; i <differ; a=
""
bar=
""
differ=
"-differ;"
else
=
""
for
=
""
i=
"0;"
if
=
""
li=
""
lock_for_req_back_next=
"0;"
resource_name=
"$(this).attr("
href
").split("
resource_name=
")[1];"
side=
""
siderbar_index=
"="
ul.page-sidebar-menuli=
""
ul.sub-menu=
""
var
=
""
> span.arrow
').addClass('
open
');
$(this).parents('
.sub-menu
').show();
});
$(this).parent('
li
').parents('
li
').addClass('
active open
');
return false;
} else {
$('
.sub-menu').hide();
}
});
$(
"ul.page-sidebar-menuli"
).not(
".open"
).find(
"ul"
).hide();
}
}
</differ;>
|