javascript ---> XHR (XMLHttpRequet) objects

XHR:

// XHR(XMLHttpRequest):为向服务器发送请求和解析服务器响应提供了流畅的接口
// 能够以异步方式从服务器取得更多信息,意味着用户点击后,可以不必刷新页面也能取得新数据
// 换句话说,可以使用XHR对象获取新数据,然后再通过DOM将新数据插入到页面中.

XMLHttpRequest object:

// IE5是第一款引入XHR对象的浏览器.再IE5中,XHR对象是通过MSXML库中的一个ActiveX对象实现的.
// 因此,在IE中可能会遇到三种不同版本的XHR对象:
// IE7之前的生成xhr对象
function createXHR() {
    if(typeof arguments.callee.activeXString != "string") {
        var version = ["XSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
                       "XSXML2.XMLHttp"],
            i, len;
        for (i=0, len = versions.length; i < len; i++) {
            try {
                new activeXObject(versions[i]);
                arguments.callee.activeXString = versions[i];
            } catch (ex) {
                // jump this
            }
        }
        return new ActiveXObject( arguments.callee.activeXString);
    }
}

// 支持IE7及更高的版本,生成xhr对象
function createXHR() {
    if (typeof XMLHttpRequest != "undefined") {
        return new XMLHttpRequest();
    } else if (typeof ActiveXObject != "undefined") {
        if (typeof arguments.callee.activeXString != "string") {
            var versions = [ "MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
                             "MSXML2.XMLHttp"],
            i, len;
        for( i =0, len =versions.length;  i< len; i++) {
            try {
                new ActiveXObject(versions[i]);
                arguments.callee.activeXString = versions[i];
                break;
            } catct(ex) {
                // 跳过
            }
        }
        return new ActiveXObject(arguments.callee.activeXString);
    } else {
        throw new Error("No XHR object avilable.");
    }
}

Xhr.open () creates a request to be sent:

// open():它接受3个参数:要发送的请求的类型("get","post"等)、请求的URL和是否异步发送请求的布尔值
// 利用上面定义的方法
var xhr = createXHR();
xhr.open("get", "example.php", false);

// 以上代码会启动一个针对example.php的GET请求.
// 注1:以上的URL是相对于执行代码的当前页面
// 注2:open方法并不会真正发送请求,而只是启动一个请求以备发送
// 注3:只能像同一个域中使用相同端口和协议的URL发送请求.

Xhr.send () request transmission to be transmitted:

// send():接收一个参数,即要作为请求主体发送的数据.如果不需要通过请求主体发送数据,则必须传入null.
// 利用上面创建的待发送请求
xhr.send(null);

Several properties of XHR server response:

// responseText: 作为响应主体被返回的文本
// responseXML: 如果响应的内容类型是"text/xml" 或”application/xml",这个属性中将保存包含着响应数据的XML DOM文档
// status: 响应的HTTP状态
// statusText: HTTP状态的说明

// 可以像下面这样检测返回的status
xhr.open("get", url, false);   // 同步方式
xhr.send(null);

if((xhr.status >= 200 && xhr.status <300) || xhr.status == 304) {
    alert(xhr.responseText);  // 响应主体
} else {
    alert("Request was unsuccessful: " + xhr.status);
}
// 注1:状态码304,代表请求资源未修改

XHR asynchronous transmission request readyState properties:

// 该属性表示请求 / 响应过程的当前活动阶段
// xhr.readyState == 0:未初始化,尚未调用open方法
// xhr.readyState == 1: 启动,调用了open方法,但未调用send方法
// xhr.readyState == 2: 发送,已经调用了send方法,但并未收到响应
// xhr.readyState == 3: 接收,已经接收到部分响应数据
// xhr.readyState == 4: 完成,已经接收到全部响应数据,而且已经可以在客户端使用了

// 看下面一个例子:
var xhr = createXHR();
xhr.onreadystatechange = function () {
    if ( xhr.readyState == 4) {
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
            alert(xhr.responseText);
        } else {
            alert("Request was unsuccessful: " + xhr.stauts);
        }
    }
};
xhr.open("get", url, true);    // 异步发送请求
xhr.send(null);

// 注1:每次readyState改变时,都会触发一次onreadystatuschange事件
// 注2:以上onreadystatuschange事件是通过DOM0级方法添加的(原因,DOM2级添加方法仅支持部分浏览器)

// xhr.abort():用于在接收到响应前,取消异步请求
xhr.abort();

HTTP header information:

// Accept: 浏览器能够处理的内容类型
// Accept-Charset: 浏览器能够显示的字符集
// Accept-Encoding: 浏览器能够处理的压缩编码
// Accept-Language: 浏览器当前设置的语言
// Connection: 浏览器域服务器之间连接的类型
// Cookie: 当前页面设置的任何Cookie
// Host: 发出请求的页面所在的域
// Referer: 发出请求的页面的URI
// User-Agent: 浏览器的用户代理

// 使用xhr.setRequestHeader发送请求头部信息.必须位于xhr.open和xhr.send之间
var xhr = createXHR();
xhr.onreadystatechange = function () {
    if ( xhr.readyState ==4 ){
        if(( xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
            alert( xhr.responseText);
        } else {
            alert("Request was unsuccessful: " + xhr.status);
        }
    }
}
xhr.open("get", url, true);
xhr.setRequestHeader("MyHeader", "MyValue");
xhr.send(null);

// xhr.getResponseHeader():可以取得响应的响应头部信息
// xhr.getAllResponseHeaders():可以取得一个包含所有头部信息的长字符串
var myHeader = xhr.getResponseHeader("MyHeader");
var allHeaders = xhr.getAllResponseHeaders();

GET request:

// 用于向服务器查询某些信息,可以将查询字符串参数追加到URL的末尾
// 查询字符串中的每个参数的名称和值都必须使用encodeURIComponent()进行编码,然后才能放到URL的末尾

// addURLParam
function addURLParam(url, name, value) {
    url += (url.indexOf("?") == -1 ? "?" : "&");
    url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
    return url;
}

// use
var url = "example.php";
url = addURLParam(url, "name", "Nicholas");   // example.php?name=Nicholas
url = addURLParam(url, "book", "Professional JavaScript"); // example.php?name=Nicholas&book=Professional%JavaScript

xhr.open("get", url, false);

POST request:

// 通常用于向服务器发送应该被保存的数据

// 使用XHR来模仿表单提交
function submitData() {
    var xhr = createXHR();
    xhr.onreadystatechange = function () {
        if ( xhr.readyState == 4) {
            if (( xhr.status >=200 && xhr.status < 300) || xhr.status == 304) {
                alert(xhr.responseText);
            } else {
                alert("Request was unsuccessful: " + xhr.status);
            }
        }
    };
    xhr.open("post", "postexample.php", ture);
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    var form = document.getElementById("user-info");
    xhr.send(serialize(form));   // serialize是标准化表单元素的函数
}

// 附:serialize()
function serialize (form) {
    var parts = [],
    i,len,j,optLen,option,optValue;
    
    for( i =0, len = form.elments.length; i< len; i ++) {
        filed = form.ekenebts[i];
         
        switch(field.type) {
            case "select-one":
            case "select-multiple":
             
            if(field.name.length) {
                for(j = 0, optLen = field.options.length; j < optLen; j++) {
                    option = field.options[j];
                    if(option.selected) {
                        optValue = "";
                        if ( option.hasAttribute) {
                            optValue = (option.hasAttribute("value") ?
                                        option.value : option.text);
                        } else {
                            optValue = (option.attribute["value"].specified ?
                                        option.value : option.text);
                        }
                        parts.push(encodeURIComponent(field.name) + "=" +
                                   encodeURIComponent(optValue));
                        }
                    }
                }
                break;
            case undefined:
            case "file":
            case "submit":
            case "reset":
            case "button":
                break;
            case "radio":
            case "checkbox":
                if(!field.checked) {
                    break;
                }
            default:
                if(field.name.length) {
                    parts.push(encodeURIComponent (field.name) + "=" +
                               encodeURIComponent (field.value));
                }
        }
    }
    return parts.join("&");
}

// 注:在发送相同大小数据的时候,GET请求的速度最多可达POST请求速度的2倍

Reference "JavaScript Advanced Programming" (3rd edition) P436 ~ P437, P571 ~ P578

Guess you like

Origin blog.csdn.net/piano9425/article/details/93410955