在项目中遇到这样一种情况,在home页面选中资源并键入查询关键字,然后跳转到另一个页面result展示查询结果;这就需要将home页面选中的资源信息和关键字传递到result页面,在result页面加载是调用后台服务获取查询结果。
这里遇到一个难点:选中资源信息包括分类id和资源id,当选中的资源比较多时(可能几百个)这个信息比较大。
最开始我是直接在http url中将参数传到result页面的(由于要在原页面完成跳转,所以不能用windows.open(url , property)来实现);
首先我将所有资源信息,以一定的规律拼成一个字符串(url只能携带字符串类型参数),然后在result页面再做一次解码操作。当选中资源比较少时,这种方法当然是很有效的。但是当资源量比较大时就不可行了,会出现url 超长错误,这是因为http url长度是有限制的。
微软官方有说明:
Firefox (Browser)
对于Firefox浏览器URL的长度限制为65,536个字符,但当我测试时,最大只能处理8182个字符,这是因为url的长度除了浏览器限制外,还会受Web服务器的限制,而我本机使用的是ubuntu apache服务器,最大处理能力为8192个字符(相差10个字符,不知道是什么原因),一旦超过这个长度,服务器就返回如下错误信息。
Safari (Browser)
URL最大长度限制为 80,000个字符。
Opera (Browser)
URL最大长度限制为190,000个字符。
Google (chrome)
url长度一旦超过8182个字符时,出现如下服务器错误:
写道
Request-URI Too Large
The requested URL's length exceeds the capacity limit for this server.
Apache/2.2.12 (Ubuntu) Server at 127.0.1.1 Port 80
Apache (Server)
能接受最大url长度为8,192个字符,但我的测试数据是8,182,10个字符,差别不在,数据具体符合。
Microsoft Internet Information Server(IIS)
能接受最大url的长度为16,384个字符。
通过上面的数据可知,为了让所有的用户都能正常浏览,我们的URL最好不要超过IE的最大长度限制(2038个字符)
由于url长度限制问题,我又开始寻找下一种实现方法。我尝试用cookie。
JavaScript是运行在客户端的脚本,因此一般是不能够设置Session的,因为Session是运行在服务器端的。 而cookie是运行在客户端的,所以可以用JS来设置cookie.两个页面需要用到同一个变量,这种情况也是比较适合用到cookie的。cookie也常用来存放系统用户登录信息。
cookie的结构,简单地说:cookie是以键值对的形式保存的,即key=value的格式。各个cookie之间一般是以“;”分隔。
//将用户id存入cookie
document.cookie="userid="+data.result.id;
function getCookie($name){
var strCookie=document.cookie.split(";");
var userid;
for(var o in strCookie){
if(strCookie[o].indexOf($name)!=-1){
userid=strCookie[o].replace($name,"").replace("=","").trim();
}
}
}
设置过期时间来使cookie过期以间接达到清除的目的或者将其内容设置为空
//删除cookie中指定变量函数
function delCookie($name){
var myDate=new Date();
myDate.setTime(-1000);//设置时间
document.cookie=$name+":''; expires="+myDate.toGMTString();
}
通过cookie实现了传参,但偶尔会出现参数信息变少,或是cookie参数值修改后而没有改变等问题。查询才知:cookie存在了url同样的问题,cookie也有大小限制。所以cookie只适合比较‘小’的数据参数保存。
总之,在进行页面cookie操作的时候,应该尽量保证cookie个数小于20个,总大小 小于4KB
我们项目页面用的AngularJS框架,这是我就想通过controller来实现传参应该是可行的,将home页面选中的参数信息传到父controller然后result再去取父controller的参数值就可以了。
先简单介绍下AngularJs中事件广播:
$on(name,handler)注册一个事件处理函数,该函数在特定的事件被当前作用域收到(从父级或者子级作用域)时将被调用。
$emit(name,args)向当前父作用域发送一个事件,直至根作用域。
$broadcast(name,args)向当前作用域下的子作用域发送一个事件。
name表示事件名称
args表示事件传播的数据
handler表示在接受到传递时要执行的回调,该回调中有event参数,表示事件
在home页面
将改变值后的参数发送到父容器。
$scope.selected_infomations=concatIds;
$scope.$emit("change", $scope.selected_infomations);
//页面跳转
window.location.href="#/telantSearch_jq.html?searchKeywords="+$scope.searchKeywords+"&homonymFlag="+$scope.homonymFlag+"&synonymFlag="+$scope.synonymFlag;
在父controller中
接收子容器推过来的参数,并且将参数广播到所有子容器
$scope.selected_infomations='';
$scope.$on('change', function(event,data){
$scope.selected_infomations=data;
console.log(data);
});
在result页面
if($scope.selected_infomations=='')
$scope.selected_infomations=window.parent.name
var concatIds=$scope.selected_infomations;
还存在一个问题(页面刷新参数保留),就是result页面刷新就会清空参数,这时可以先用window.parent.name保存参数,刷新后再取出即可,如result页面代码实现。