您的位置:首页 > 理论基础 > 计算机网络

2使用XMLHttpRequest对象

2016-07-12 16:16 375 查看
在使用XMLHttpRequest对象发送请求和处理响应之前,必须先使用javascript创建一个XMLHttpRequest对象。前面已经讲解如何在IE浏览器和非IE浏览器中创建XMLHttpRequest对象。

1XMLhttpRequest对象的方法和属性

abort()。停止当前请求,重新设置请求对象XMLHttpRequest的状态.

getResponseHeader("String"),返回指定首部的串值

open("method","url"),建立对服务器的调用,method参数可以是GET,POST或PUT。url参数可以是相对URL或绝对URL。这个方法还包括3个可选参数。

send(content),向服务器发送请求

setRequestHeader("header","value"),把指定首部设置为所提供的值。在设置任何首部之前必须先调用open().

下面详细介绍这些方法

void open(string method,string url,boolean,asynch,string username,string password),这个方法建立对服务器的调用。这是初始化一个请求的纯脚本方法。它有两个必要的参数,还有3个可选参数。要提供调用特定方法GET,POST,PUT;还要提供所调用资源的URL。另外还可以传递一个Boolean值,指示这个调用是异步还同步,默认为true表示异步。某些情况下这个参数设置为false也是有用的,必须在持久存储页面之前可以先验证用户的输入。最后两个参数允许指定一个特定的额用户名和密码。

void send(content),这个方法具体相服务器发出请求,如果请求声明为异步的,这个方法就会立即返回,否则它会等待直到接收到响应为止。可选参数可以是DOM对象的实例,输入流或串。传入这个方法的内容作为请求体的一部分发送。

void setRequestHeader(string header,string value),这个方法为Http请求中的一个给定的首部设置值。它有两个参数,第一个串表示要设置的首部,第二个串表示要在首部中放置的值。需要说明,这个方法在调用open()之后才能调用。

string getAllResponseHeader(),它返回一个串,其中包含Http请求的所有响应首部,首部包括Content-Length,Date和URI

string getResponseHeader(string header),这个方法与getAllResponseHeaders()是对应的,不过它有一个参数表示你希望得到的指定首部值,并且把这个作为串返回。

XMLHttpRequest属性

Onreadystatechange,每个状态改变时,都会出发这个事件处理器。通常会调用一个JavaScript函数。

readyState,请求的状态。有5个可取值:0=未初始化,1=正在加载,2=已加载,3=交互中,4=完成

responseText,服务器的响应,表示为一个串。

responseXML,服务器的响应,表示为XML,这个对象可以解析为一个DOM对象(用于解析服务器返回的xml串)。如:

xmlHttp.responseXML.getElementsByTagName("message")[0].firstChild.data;

Status,服务器的HTTP状态码(200对应正常,404对应Not Found(未找到),受到保护或者禁止访问的 403 和 401 ,405 表示不允许使用诸如发送 HEAD 请求之类不可接受的请求方法,而 407 则表示需要进行代理认证等)

statusText,HTTP状态的相应文本(OK或者Not Found(未找到)等等)

2处理服务器响应

XMLHttpRequest对象提供了两个可以用来访问服务器响应的属性。第一个属性responseText将响应提供为一个串,第二属性responseXML将相应提供为一个XML对象。一些简单的用例很合适按简单文本来获取响应,如将响应显示在警告框中,或响应指示指示成功还是失败的词。

如果结合html元素的innerHTML属性,responseText属性会变得非常有用。这是一个简单的串,表示一组开始标记和结束标记之间的内容。通过结合使用responseText和innerHTML,服务器就能生产或生成HTML内容。

例如:我们可以使用innerHTML属性将下面xml文件的内容显示在HTML中。

<?xml version="1.0"?>

<table border="1">

<tbody>

<tr>

<th>Activity Name</th>

<th>Location</th>

<th>Time</th>

</tr>

<tr>

<td>Watersking></td>

<td>Dock #1</td>

<td>9:00 AM</td>

</tr>

</tbody>

</table>

在这个jsp文件中上面的xml,通过responseText和innerHTML被解析成为一个表格。

<%@ page language="java" contentType="text/html;charset=UTF-8"%>

<html>

<head>

<title>一个简单的例子</title>

<script type="text/javascript" language="javascript">

var xmlHttp = false;

function makeRequest(url) {

xmlHttp = false;

if (window.XMLHttpRequest) { // Mozilla, Safari,...

xmlHttp = new XMLHttpRequest();

if (xmlHttp.overrideMimeType) {

xmlHttp.overrideMimeType('text/xml');

}

} else if (window.ActiveXObject) { // IE

try {

xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

} catch (e) {

try {

xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

} catch (e) {}

}

}

if (!xmlHttp) {

alert('Giving up :( Cannot create an XMLHTTP instance');

return false;

}

xmlHttp.onreadystatechange = alertContents;

xmlHttp.open('GET', url, true);

xmlHttp.send(null);

}

function alertContents() {

if (xmlHttp.readyState == 4) {

if (xmlHttp.status == 200) {

document.getElementById("results").innerHTML+=xmlHttp.responseText;

} else {

alert('There was a problem with the request.');

}

}

}

</script>

</head>

<body>

<span

style="cursor: pointer; text-decoration: underline"

onclick="makeRequest('innerHTML.xml')" id="results">

Make a request

</span>

</body>

</html>

3W3c DOM和javascript

DOM是面向Html和xml文档的API,为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。

用于处理XML文档的DOM元素属性

childNodes,返回当前所有子元素的数组。

firstChild,返回当前的第一个下级子元素。

lastChild,返回当前元素的最后一个子元素。

nextSibling,返回紧跟在当前元素后面的元素。

previousSibling,返回紧邻当前元素之前的元素。

nodeValue,指定表示元素值的读/写属性。

parentNode,返回元素的父节点。

<response><passed>passtest</passed></response>

例:getElementsByTagName("passed")[0].firstChild.data;将返回passtest。

用于遍历XML文档的DOM元素方法

getElementById(id),获取指定唯一ID属性值文档中的元素。

getElementsByTagName(name),返回当前元素中所有指定标记名的子元素的数组。

hasChildNodes(),返回一个布尔值,指示元素是否有子元素。

getAttribute(name),返回元素的属性值,属性由name指定。

下面的一个例子将在javascript显示parseXML.xml中的内容。

parseXML.xml如下:

<?xml version="1.0" encoding="UTF-8"?>

<states>

<north>

<state>Minnesota</state>

<state>Iowa</state>

<state>North Dakata</state>

</north>

<south>

<state>Texas</state>

<state>OKlahoma</state>

<state>Louisana</state>

</south>

<east>

<state>New York</state>

<state>North Carolina</state>

<state>Massachusetts</state>

</east>

<west>

<state>California</state>

<state>Oregon</state>

<state>Nevada</state>

</west>

</states>

我们将在parseXML.jsp中显示parseXML.xml中所有state标记的值。

<%@ page contentType="text/html;charset=UTF-8" language="java"%>

<html>

<head>

<script language="javascript">

var xmlHttp=false;

function createXMLHttpRequest(){

if (window.XMLHttpRequest) { // Mozilla, Safari,...

xmlHttp= new XMLHttpRequest();

if (xmlHttp.overrideMimeType) {

xmlHttp.overrideMimeType('text/xml');

}

} else if (window.ActiveXObject) { // IE

try {

xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

} catch (e) {

try {

xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

} catch (e) {}

}

}

if (!xmlHttp) {

alert('Giving up :( Cannot create an XMLHTTP instance');

return false;

}

}

function startRequest(){

createXmlHttpRequest();

xmlHttp.onreadystatechange=handleStateChange;

xmlHttp.open("GET","parsetXML.xml",true);

xmlHttp.send(null);

}

function handStateChange(){

if(xmlHttp.readyState==4){

if(xmlHttp.status==200){

listAllStates();

}

}

}

function listAllStates(){

//xmlHttp.responseXML得到服务器的响应,表示为XML,这个对象可以解析为一个DOM对象

var xmlDoc=xmlHttp.responseXML;

//返回所有是state标记名的元素数组

var allStates=xmlDoc.getElementsByTagName("state");

outputList("All States in Document",allStates);

}

function outputList(title,states){

var out=title;

var currentState=null;

for(var i=0;i<states.length;i++){

currentState=states[i];

out=out+"\n"+currentState.childNodes[0].nodeValue;

}

alert(out);

}

</script>

</head>

<body>

<form>

<input type="button" value="view all Listed States" onClick="startRequest()"/>

</form>

</body>

</html>

4Web浏览器中动态创建内容

HTML动态创建内容时所用的W3C DOM属性和方法

属性:

childNodes,返回当前元素所有子元素的数组

firstChild,返回当前元素的第一个下级子元素

lastChild,返回当前元素的最后一个子元素

nextSibling,返回紧跟在当前元素后面的元素

nodeValue,指定表示元素值的读/写属性

parentNode,返回元素的父节点

previousSibling,返回紧邻当前元素之前的元素

方法:

document.createElement(tagName),文档对象上的createElement方法可以创建由tagName指定的元素。如果以串div作为方法参数就会生成一个div元素。

document.createTextNode(text),文档对象的createTextNode方法会创建一个包含静态文本的节点。

<element>.appendChild(childNode),appendChild方法将指定的节点增加到当前元素的子节点列表。例如可以增减一个option元素作为select元素的子节点。

<element>.getAttribute(name),<element>.setAttribute(name,value)这些方法分别获得和设置元素中name属性的值。

<element>.insertBefore(newNode,targetNode),这个方法将节点newNode作为当前元素的子节点插到targetNode)元素前面。

<element>.removeAttribute(name),这个方法从元素中所以删除属性name

<element>.replaceChild(childNode),这个方法从元素中删除子元素childNode

<element>.replaceChild(newNode,oldNode),这个方法将节点oldNode替换为节点newNode

<element>.hasChildnodes(),这个方法返回一个布尔值,指示元素是否有子元素。

<element>.removeChild(childNode),这个方法从元素中删除子childNode

IE的W3C Dom和javascript实现最受限制,例如,如果使用appendChild将<tr>元素直接增加到<table>中,则在IE中这一行并不出现,但在其他浏览器中却会显示出来。对此解决办法是将<tr>元素增加到表的<tbody>元素中,这种办法在所有浏览中都能正确工作。另外在IE中不能使用setAttribute设置style属性,最能保证浏览器兼容的技术不是<element>.setAttribute("style","font-weight:bold;")而是 <element>.style.cssText="font-weight:bold;"

5发送请求参数

大多数情况下,向服务器发送一个请求而没有任何请求参数是没有什么意义的,如果没有请求参数,服务器就得不到上下文数据,也无法根据上下文数据为客户创建个性化响应。要想充分发挥Ajax技术的强大功能,这要求你向服务器发送一些上下文数据。

*****************************

Ajax的Get和Post的区别

GET方式可以传送简单的数据,但是大小一般限制在1KB之下。

GET方法把值作为名/值对放在请求URL中传递。资源URL的最后有一个问号?,问号后面就是名/值对。名/值对采用name=value的形式,各个名/值对之间用与号&分隔。例如:
http://localhost/yourApp?firstName=Adam&middleName=Chirstopher
使用get方式需要注意:

对于get请求(或凡涉及到url传递参数的),被传递的参数都要先经encodeURIComponent方法处理.例:var url = "update.php?username=" +encodeURIComponent(username) + "&content=" +encodeURIComponent(content)+"&id=1"

POST方法传输的数据量大,可以达到2M。

POST方法向服务器发送命名参数时,与采用GET方法几乎是一样的。类似于GET方法,POST方法会把参数编码为名/值对,形式为name=value,每个名/值对之间也用与号&分隔。这个方法的主要区别在于,POST方法将参数串放在请求体中发送,而GET方法是将参数追加到URL中发送。POST方法参数将在Send()方法中发送,例: xmlHttp.send(name); 如果是get方式,直接 xmlHttp.send(null);

使用Post方式需注意:

设置header的Context-Type为application/x-www-form-urlencode确保服务器知道实体中有参数变量.通常使用XmlHttpRequest对象的SetRequestHeader("Context-Type","application/x-www-form-urlencoded;")。例:

xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

注: encodeURIComponent返回一个包含了 charstring 内容的新的 String 对象(Unicode 格式), 所有空格、标点、重音符号以及其他非 ASCII 字符都用 %xx 编码代替,其中 xx 等于表示该字符的十六进制数。例如,空格返回的是 "%20"。字符的值大于 255 的用 %uxxxx 格式存储。参见JavaScript 的 encodeURIComponent()方法.(application/x-www-form-urlencoded同encodeURIComponent做法一样)

关于application/x-www-form-urlencoded:

form的enctype属性为编码方式,常用有两种:application/x-www-form-urlencoded和multipart/form-data,默认为application /x-www-form-urlencoded。 当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1& amp;name2=value2...),然后把这个字串append到url后面,用?分割,加载这个新的url。 当action为post时候,浏览器把form数据封装到http
body中,然后发送到server。 如果没有type=file的控件,用默认的application/x-www-form-urlencoded就可以了。 但是如果有type=file的话,就要用到multipart/form-data了

HTML使用规约理论上推荐采用GET方法,从这可以看出,获取数据时应当使用GET方法,如果因为存储,更新数据或发送电子邮件操作改变了数据模型的状态,这时建议使用POST方法。

*****************************

AJAX乱码问题

产生乱码的原因:

1、xtmlhttp返回的数据默认的字符编码是utf-8,如果客户端页面是gb2312或者其它编码数据就会产生乱码。解决方法:若客户端是gb2312编码,则在服务器指定输出流编码为gb2312。

2、post方法提交数据默认的字符编码是 utf-8,如果服务器端是gb2312或其他编码数据就会产生乱码

post方法提交数据默认的字符编码是utf-8,如果服务器端是gb2312或其他编码数据就会产生乱码.

解决办法:服务器端和客户端都使用utf-8编码.

gb2312:header('Content-Type:text/html;charset=GB2312');

utf8:header('Content-Type:text/html;charset=utf-8');

对于application/x-www-form-urlencoded可以顺利处理英文;在处理中文时,request.getParameter("parameter")根本取不到值参数parameter的中文值。

*******************

下面的getAndPostExample.jsp中展示了get,post方法像服务器发送数据

<%@ page language="java" contentType="text/html;charset=UTF-8"%>

<html>

<head>

<title>Sending Request Data Using GET and POST</title>

<script type="text/javascript">

var xmlHttp;

function createXMLHttpRequest(){

if (window.XMLHttpRequest) { // Mozilla, Safari,...

xmlHttp= new XMLHttpRequest();

if (xmlHttp.overrideMimeType) {

xmlHttp.overrideMimeType('text/xml');

}

} else if (window.ActiveXObject) { // IE

try {

xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

} catch (e) {

try {

xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

} catch (e) {}

}

}

if (!xmlHttp) {

alert('Giving up :( Cannot create an XMLHTTP instance');

return false;

}

}

function createQueryString(){

var firstName=document.getElementById("firstName").value;

var middleName=document.getElementById("middleName").value;

var birthday=document.getElementById("birthday").value;

var queryString="firstName="+firstName+"&middleName="+middleName+"&birthday="+birthday;

return queryString;

}

function doRequestUsingGET(){

createXMLHttpRequest();

var query="GetAndPostExample.do";

//因为是在struts中,url可以为GetAndPostExample.do,但是如果在Servlet中,查询串会追加到请求url中的。当然即使我们在struts中,url追加了查询串(queryString),也是可以的,只是没有必要这么麻烦。

//query=query+"?"+createQueryString();

xmlHttp.onreadystatechange=handleStateChange;

xmlHttp.open("GET",query,true);

xmlHttp.send(null);

}

function doRequestUsingPOST(){

createXMLHttpRequest();

var url="GetAndPostExample.do";

var queryString=createQueryString();

xmlHttp.open("POST",url,true);

xmlHttp.onreadystatechange=handleStateChange;

xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");

//application/x-www-form-urlencoded含义是表示客户端提交给服务器文本内容的编码方式 是URL编码,即除了标准字符外,每字节以双字节16进制前加个“%”表示

//因为是在struts中,url可以为GetAndPostExample.do,post方法时,XMLHttpRequest对象的send()方法时不用发送查询串。但是在Servlet中,send()方法要发送查询串(queryString);当然即使我们在struts中使用send()方法发送了查询串,也是可以的。只是不同这么麻烦。

//xmlHttp.send(queryString);

xmlHttp.send(null);

}

function handleStateChange(){

if(xmlHttp.readyState==4){

if(xmlHttp.status==200){

parseResults();

}}}

function parseResults(){

var reponseDiv=document.getElementById("serverResponse");

if(reponseDiv.hasChildNodes()){

reponseDiv.removeChild(reponseDiv.childNodes[0]);

}

var responseText=document.createTextNode(xmlHttp.responseText);

reponseDiv.appendChild(responseText);

}

</script>

</head>

<body>

<h1>Enter your first name,middlename,and birthday:</h1>

<form method="get">

<table><tbody>

<tr><td>First name:</td>

<td><input type="text" id="firstName"/>

</tr>

<tr>

<td>Middle name:</td>

<td><input type="text" id="middleName"/>

</tr>

<tr>

<td>Birthday:</td>

<td><input type="text" id="birthday"/>

</tr>

</tbody></table>

<input type="button" value="Send parameters using GET" onClick="doRequestUsingGET();"/>

<br/><br/>

<input type="button" value="Send parameters using POST" onclick="doRequestUsingPOST();"/>

</form>

<br/>

<h2>Server Response:</h2>

<div id="serverResponse"></div>

</body>

</html>

与getAndPostExample.jsp对应的ActionForm:

package mypack;

import org.apache.struts.action.ActionMapping;

import org.apache.struts.action.ActionErrors;

import org.apache.struts.action.ActionMessage;

import org.apache.struts.action.ActionForm;

import javax.servlet.http.*;

import javax.servlet.*;

public class GetAndPostForm extends ActionForm{

private String firstName;

private String middleName;

private String birthday;

public String getFirstName(){

return firstName;

}

public void setFirstName(String firstName){

this.firstName=firstName;

}

public String getMiddleName(){

return middleName;

}

public void setMiddleName(String middleName){

this.middleName=middleName;

}

public String getBirthday(){

return birthday;

}

public void setBirthday(String birthday){

this.birthday=birthday;

}

}

处理getAndPostExample.jsp表单数据的Action类:

package mypack;

import javax.servlet.*;

import javax.servlet.http.*;

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.Action;

import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;

import java.io.*;

public class GetAndPostAction extends Action{

public ActionForward execute(

ActionMapping mapping,

ActionForm form,

HttpServletRequest request,

HttpServletResponse response)

throws Exception{

GetAndPostForm gpf=(GetAndPostForm)form;

String firstName=gpf.getFirstName();

String middleName=gpf.getMiddleName();

String birthday=gpf.getBirthday();

String responseText="Hello"+firstName+" "+middleName+" "+birthday;

PrintWriter out=response.getWriter();

//这里输出的字符串responseText将是在javascript中的XMLHttpRequest对象responseText属性的值。

out.println(responseText);

out.close();

return null;

}

}

****************

上例中我们在一个struts实例中演示了XMLHttpRequest对象的与服务器的异步交互。我们得到,在struts中,不论为get还是post方法:

xmlHttp.open("POST",url,true)建立对服务器的调用,url就是服务器端配置的用于处理表单数据的Action(GetAndPostExample.do)。

send(null),向服务器发送请求,send()方法直接发送一个null值就可以了。不过这只是在<form>..</form>表单中并有ActionForm类与之对应,所以我们发送了null,也可以通过ActionForm类获取表单的内容;但是如果不在<form>中,则我们还是不要使用send(null)否则就得不到表单的内容。

XMLHttpRequest对象的responseText属性将收到服务器端(Action)输出的响应。

***************

87
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: