背景:在项目中遇到一个问题,在a标签的onclick事件中加入了跨域请求,但必须保证跨域请求发出去之前,页面不会跳转走。
解决:用$.getJSON()方法进行跨域请求,因为$.getJSON()方法不支持同步请求设置,所以用js实现休眠保证请求的发出,在处理请求的php代码里加上保证处理必须完成的设置,就可以既保证请求发出,也保证请求处理完成。
参考文章:1.http://blog.163.com/zhangjiang_love/blog/static/8534413720133231306665/
2.http://www.leakon.com/archives/22
涉及代码如下:
js代码:
// 跨域请求处理,always是在请求返回后不论状态是成功或者失败都进行处理
$("#ajumpsite").click(function(){
var url = SITE_URL+'/index.php?app=searchlog&act=put_loginfo_rabbitmq&logtype=2&condition_type=';
url += condition_type + '&condition_val=';
// 先用encodeURIComponent保证中文不乱码,再用base64加密保证特殊符号不会被服务过滤掉
url += base64encode(encodeURIComponent(condition_val))
$.getJSON(url+'&jsoncallback=?', function(data) {
}).always(function() {
alert("kkkk");
});
// 设置js休眠保证请求的发出
WaitTime(300);
/*
* 另一种实现先将a标签href属性赋值变量存起来,再将href属性写为"javascript:void(0);",
* 最后在always处理里面用location.href=存储href值的变量 完成跳转
*/
});
/* js休眠实现 start */
// 获取当前时间表示的微秒数
function GetCurrentTimeSeconds()
{
var d=new Date();
var hour=d.getHours();
var minute=d.getMinutes();
var second=d.getSeconds();
return (hour * 60 * 60 + minute * 60 + second)*1000;
}
// 让程序等待指定的微秒数
// sec:等待微秒数
function WaitTime(sec)
{
var startPos = GetCurrentTimeSeconds();
var pass;
while (true) {
pass = GetCurrentTimeSeconds() - startPos;
if (pass >= sec) {
break;
}
}
}
/* js休眠实现 end */
//base64加密字符串
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
function base64encode(str) {
var out, i, len;
var c1, c2, c3;
len = str.length;
i = 0;
out = "";
while(i < len) {
c1 = str.charCodeAt(i++) & 0xff;
if(i == len)
{
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt((c1 & 0x3) << 4);
out += "==";
break;
}
c2 = str.charCodeAt(i++);
if(i == len)
{
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
out += base64EncodeChars.charAt((c2 & 0xF) << 2);
out += "=";
break;
}
c3 = str.charCodeAt(i++);
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
out += base64EncodeChars.charAt(c3 & 0x3F);
}
return out;
}
php代码:
public function put_loginfo_rabbitmq(){
ignore_user_abort (true);
//加载rabbitmq文件
import('rabbitmq.lib');
//实例化对象
$rabbitMq = new RabbitMq();
$jsonArr = array();
$jsonArr['visitdate'] = date('Ymd', gmtime()+3600*8);
$jsonArr['visittime'] = gmtime()+3600*8;
if ($_GET['logtype'] == 2) // 商品搜索日志
{
// array("condition_type"=>'',"condition_val"=>'','visittime'=>'','visitdate'=>'');
// 搜索类型(1:类目 2:关键字),搜索条件
$jsonArr['condition_type'] = $_GET['condition_type'];
$jsonArr['condition_val'] = str_replace("*", " ", urldecode(base64_decode($_GET['condition_val'])));
$rabbitMq->setRabbitMqInfo(json_encode($jsonArr),"goodssearchKey","goodssearchExchange","goodssearchQueue");
// 打印此处是为了保证$.getJSON的回调方法被触发
echo $_REQUEST['jsoncallback'].'('.json_encode($jsonArr).')';
}
}