技术开发 频道

借助 Ajax 自动保存 JSF 表单,第 1 部分: 利用 XMLHttpRequest 提交

  用 Ajax 提交表单数据

  本节将展示如何使用 Ajax 向 JSF 页面发送表单数据,还会涵盖与之相关的其他一些主题,例如错误处理以及 XMLHttpRequest 对象的正确管理,这些都是防止 Web 浏览器内的内存泄漏所必须了解的。

  创建和发送 Ajax 请求

  submitFormData() 函数的代码可以在 AutoSaveScript.js 文件中找到(请参见 下载 部分),该函数使用 Ajax 请求对象向 Web 服务器提交编码后的数据。首先,它需要创建这个请求对象,如果是 Microsoft® Internet Explorer,就使用 ActiveXObject(),如果是支持 Ajax 的其他浏览器,比如 Firefox、Netscape、Mozilla、Opera 和 Safari,就使用 XMLHttpRequest()。清单 5 显示了创建 XMLHttpRequest 对象所需的代码。

  清单 5. 创建 Ajax 请求对象

function submitFormData(form) {
    var xhr;
    
if (window.ActiveXObject)
        xhr
= new ActiveXObject("Microsoft.XMLHTTP");
    
else if (window.XMLHttpRequest)
        xhr
= new XMLHttpRequest();
    
else
        return
null;
    ...
}

  编码后的表单数据被提交给由表单的 action URL 所识别的页面,使用的是特定的 HTTP method,在 JSF 表单的情况下,此方法即为 POST。submitFormData() 函数也可以同非 JSF 表单一起使用,这类表单有可能会使用默认的 GET 方法或 POST。即使这个表单没有指定 action URL,此代码仍可以工作。在这种情况下,submitFormData() 将会使用由 document.URL 获得的当前页面的 URL。编码后的表单数据可通过 getFormData() 函数从 form 对象检索到,该函数在前面已介绍过。如果此 HTTP 方法是 GET,那么编码后的数据会追加到 URL ? 字符后面。之后,submitFormData() 通过 open() 方法初始化 xhr 对象(见清单 6)。

  清单 6. 初始化 Ajax 请求对象

function submitFormData(form) {
    ...        
    var method
= form.method ? form.method.toUpperCase() : "GET";
    var action
= form.action ? form.action : document.URL;
    var data
= getFormData(form);

    var url
= action;
    
if (data && method == "GET")
        url
+= "?" + data;
    xhr.open(method, url,
true);
    ...
}

  当从服务器收到对 Ajax 请求的响应时,会调用称为 submitCallback() 的内部函数。如果 autoSaveDebug 的值为 true,这个 Ajax 回调就会发出错误信号,请求虽完成(readyState 为 4),但其状态却不对(status 不是 200)。一旦发生错误,系统就会通过 alert() 报告 xhr 对象的 status 和 statusText 属性,而且 autoSaveDebug 标记也会设为 false 以防您一次又一次地收到错误消息(因为表单保存是周期性执行的)。如果重新加载此页面,JavaScript 代码就会重新初始化,若导致 HTTP 错误的问题仍没有得到解决,您将会再次看到错误消息。这个功能非常适合开发阶段的调试之用。在实际的生产环境中,当发生错误时,与显示告警信息相比,最好是将用户重新引导到其他页面。不管何种情况,xhr 对象的 onreadystatechange 属性都必须包含一个对 submitCallback() 的引用以便此回调函数在 Ajax 请求的生命周期中能被调用(见清单 7)。

  清单 7. 回调函数

var autoSaveDebug = true;

function submitFormData(form) {
    ...        
    
function submitCallback() {
        
if (autoSaveDebug && xhr.readyState == 4
                
&& xhr.status != 200) {
            autoSaveDebug
= false;
            alert(
"Auto-Save Error: "
                
+ xhr.status + " " + xhr.statusText);
        }
    }
    xhr.onreadystatechange
= submitCallback;
    ...
}

  接下来,submitFormData() 设定 Ajax-Request 报头,它对示例应用程序是特定的,用来在服务器端识别 Ajax 请求,这将在本文后面的部分进行介绍。如果 HTTP 方法是 POST,那么 submitFormData() 函数会设置标准 Content-Type 报头并且会使用 xhr 对象的 send() 方法将表单数据提交给 JSF 页面。如果 HTTP 方法是 GET(当前未被 JSF 表单使用),那么表单数据应该已经追加到此 URL,并会用 null 参数调用 send()。在提交表单数据后,此函数返回一个对 xhr 对象的引用(见清单 8)。

  清单 8. 发送 Ajax 请求

function submitFormData(form) {
    ...        
    xhr.setRequestHeader(
"Ajax-Request", "Auto-Save");
    
if (method == "POST") {
        xhr.setRequestHeader(
"Content-Type",
            
"application/x-www-form-urlencoded");
        xhr.send(data);
    }
else
        xhr.send(
null);
    
    return xhr;
}
0
相关文章