Posts Tagged ‘ ajax

自动排队的异步Ajax请求

这两天正在为Ajax同步请求会临时锁住浏览器的问题而烦恼,没想到今天在看《JavaScript设计模式》发现了解决方法,里面有一段可以自动排队的异步Ajax请求的代码范例。看到这段代码真有种众里寻她千百度,蓦然回首,那人却在灯火阑珊处的感觉,哈哈。现在把它整理下,用着慢慢用。

var QueuedHandler = function(){
	this.queue = []; // 请求队列
	this.requestInProgress = false; // 判断当前是否己有别的请求
	this.retryDelay = 5; // 设置每次重新请求的时间,单位为秒
};
QueuedHandler.prototype = {
	request:function(method,url,callback,postVars,override){
        // 如果没有设置为覆盖模式,而且当前已经有别的请求
        if(this.requestInProgress && !override){
            this.queue.push({
                method:method,
                url:url,
                callback:callback,
                postVars:postVars
            });
		}else{
            this.requestInProgress = true;
            var xhr = this.createXhrObject();
            var that = this;

            xhr.onreadystatechange = function(){
                if(xhr.readyState !== 4) return;
                if(xhr.status === 200){
                    callback.success(xhr.responseText,xhr.responseXML);
                    // 判断请求队列是否为空,如果不为空继续下一个请求
                    that.advanceQueue();
                }else{
                    callback.failure(xhr.status);
                    // 每过一定时间重新请求
                    setTimeout(function(){
                        that.request(method,url,callback,postVars);
                    },that.retryDelay * 1000);
                }
            };

            xhr.open(method,url,true);
            if(method!=='POST')postVars = null;
            xhr.send(postVars);
        }
	},
	createXhrObject:function(){
        var methods = [
            function(){return new XMLHttpRequest();},
            function(){return new ActiveXObject('Msxml2.XMLHTTP');},
            function(){return new ActiveXObject('Microsoft.XMLHTTP');},
        ];
        for(var i=0,len=methods.length;i<len;i++){
            try{
           	 methods[i]();
            }catch(e){
            	continue;
            }
            // 如果执行到这里就表明 methods[i] 是可用的
            this.createXhrObject = methods[i]; // 记住这个方法,下次使用不用再判断
            return methods[i]();
		}

		throw new Error('SimpleHandler: Could not create an XHR object.');
	},

	advanceQueue:function(){
        if(this.queue.length === 0){
            this.requestInProgress = false;
            return;
        }
        var req = this.queue.shift();
        this.request(req.method,req.url,req.callback,req.postVars,true);
	}
};

阅读全文

Ajax同步请求会临时锁住浏览器

由于公司网页在加载时会用Ajax发送大量请求,服务器吃不消,就把Ajax请求设置为同步。但在页面加载时浏览器会出现停顿,刚开始我还以为是写的JavaScript效率不高,占用太多的内存,造成浏览器停顿现象。这两天无意中发现如果把Ajax请求设置为同步的话,浏览器会被临时锁住,在请求返回之前不能进行任何操作。它会临时中断所有的JavaScript命令,也不能点击按钮,甚至选择文本内容。

我是到这两天才发现这个问题的,和Ajax接触了这么多年才发现,看来我对Ajax基础知识了解地实在是太肤浅了,以后要加强基础知识的掌握了。关于Ajax的基础知识可以参看W3C的资料——《XMLHttpRequest》

解决方法可以参看《自动排队的异步Ajax请求》

用file_get_contents解决ajax垮域问题

在ajax运用中有时候会垮域调用文件,而浏览器为了安全会默认给这种操作提出警告,甚至直接阻止。如果是IE会弹出一个警告窗口,询问你是否继续操作,只有你同意了IE才会调用垮域的文件。而其它浏览器,如火狐Opera默认设置下则会直接提示错误,阻止调用外域文件。这会给用户不好的操作体验,如果想通过用户修改浏览器的安全设置来解决这个问题是不现实的,最好是在服务器端解决。

在服务器端可以使用一个同域的文件做为代理文件,这个代理文件将获得外域文件的内容,然后再传递给ajax。这样ajax就不是调用外域文件,而是调用同域的这个代理文件,安全问题也就解决了。

如果你的服务器端支持PHP的话,可以使用file_get_contents这个函数,看到它的名称就已经知道它有获得其它文件内容的功能了。它的详细用法可以参看PHP官方网站上的file_get_contents用法一页,下面是它的简单实例。


<?php

$serverAddress = 'http://www.julabs.com/blog/feed/';
//获得外域文件内容
$randomNumber = file_get_contents($serverAddress);
//输出内容
echo $randomNumber;

?>