AJAX发送POST、GET请求

1、发送POST请求注意事项


  POST请求必须设置ContentType请求头的值为application/x-www.form-encoded。表单的enctype默认值就是为application/x-www.form-encoded,因为是默认值,大家可能会忽略。当设置了<form>的enctype=” application/x-www.form-encoded”时,等同与设置了Cotnent-Type请求头。

  但在使用AJAX发送请求时,就没有默认值了,这需要我们自己来设置请求头:


<span style="font-size:18px;">  xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");</span>


  当没有设置Content-Type请求头为application/x-www-form-urlencoded时,Web容器会忽略请求体的内容。所以,在使用AJAX发送POST请求时,需要设置这一请求头,然后使用send()方法来设置请求体内容。

  

<span style="font-size:18px;">  xmlHttp.send("b=B");</span>


  这时Servlet就可以获取到这个参数:

<span style="font-size:18px;">AServlet:
	public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		System.out.println(request.getParameter("b"));
		System.out.println("Hello AJAX!");
		response.getWriter().print("Hello AJAX!");
	}</span>


<span style="font-size:18px;">ajax2.jsp:
<script type="text/javascript">
function createXMLHttpRequest() {
	try {
		return new XMLHttpRequest();//大多数浏览器
	} catch (e) {
		try {
			return new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			return new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
}

function send() {
	var xmlHttp = createXMLHttpRequest();
	xmlHttp.onreadystatechange = function() {
		if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
			var div = document.getElementById("div1"); //获取节点
			div.innerHTML = xmlHttp.responseText; //添加内容
		}
	};
	xmlHttp.open("POST", "/ajaxdemo1/AServlet?a=A", true); //打开连接
	xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); //设置请求头
	xmlHttp.send("b=B");
}
</script>
<h1>AJAX2</h1>
<button onclick="send()">测试</button>
<div id="div1"></div></span>


2、POST实例


  (1)功能介绍


    在注册表单中,当用户填写了用户名后,把光标移开后,会自动向服务器发送异步请求。服务器返回true或false,返回true表示这个用户名已经被注册过,返回false表示没有注册过。

    客户端得到服务器返回的结果后,确定是否在用户名文本框后显示“用户名已被注册”的错误信息!


  (2)案例分析


     regist.jsp页面中给出注册表单;

     在username表单字段中添加onblur事件,调用send()方法;

     send()方法获取username表单字段的内容,向服务器发送异步请求,参数为username;

     RegistServlet:获取username参数,判断是否为“fightfaith”,如果是响应true,否则响应false;


  (3)代码


  regist.jsp:

<span style="font-size:18px;"><script type="text/javascript">
function createXMLHttpRequest() {
	try {
		return new XMLHttpRequest();
	} catch (e) {
		try {
			return new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			return new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
}

function send() {
	var xmlHttp = createXMLHttpRequest();
	xmlHttp.onreadystatechange = function() {
		if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
			if(xmlHttp.responseText == "true") {
				document.getElementById("error").innerHTML = "用户名已被注册!";
			} else {
				document.getElementById("error").innerHTML = "";
			}
		}
	};
	xmlHttp.open("POST", "/ajaxdemo1/BServlet", true);
	xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	var username = document.getElementById("username").value;
	xmlHttp.send("username=" + username);
}
</script>
<h1>注册</h1>
<form action="" method="post">
用户名:<input id="username" type="text" name="username" onblur="send()"/><span id="error"></span><br/>
密 码:<input type="text" name="password"/><br/>
<input type="submit" value="注册"/>
</form></span>


  RegistServlet.java:

<span style="font-size:18px;">	public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		String username = request.getParameter("username");

		if("fightfaith".equals(username)) {
			response.getWriter().print(true);
		} else {
			response.getWriter().print(false);
		}
	}</span>


3、GET实例:省市二级联动


  (1)待实现功能


AJAX发送POST、GET请求_第1张图片



    select.jsp:

<span style="font-size:18px;"><h1>省市联动</h1>
省:
<select name="province" id="province">
	<option>===请选择===</option>
</select>
市:
<select name="city" id="city">
	<option>===请选择===</option>
</select></span>


    当select.jsp页面打开时,向服务器发送异步请求,得到所有省份的名称(文本数据)。然后使用每个省份名称创建<option>,添加到<select name=”province”>中。

    为<select name=”province”>元素添加onchange事件监听。当选择的省份发生变化时,再向服务器发送异常请求,得到当前选中的省份下所有城市(XML数据)。然后客户端解析XML文档,使用每个城市名称创建<option>,添加到<select name=”city”>元素中。


  (2)代码


    服务器端:使用china.xml保存所有省份和城市名称:


<span style="font-size:18px;">china.xml
<?xml version="1.0" encoding="utf-8"?>
<china>
	<province name="北京">
		<city>东城区</city>
		<city>西城区</city>
        ……
	</province>
	<province name="天津">
		<city>和平区</city>
		<city>河东区</city>
        ……
	</province>
	<province name="河北">
		<city>保定</city>
		<city>衡水</city>
        ……
	</province>
……
</china></span>


       ProvinceServlet:负责把所有省份名称响应给客户端,这需要使用dom4j解析china.xml,得到所有<province>元素的name属性值,连接成一个字符串发送给客户端;

       CityServlet:负责得到某个省份元素,然后以字符串形式发送给客户端;


      ProvinceServlet.java:

<span style="font-size:18px;">public class ProvinceServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		// 注意设置编码
		response.setContentType("text/html;charset=utf-8");
		
		// 使用DOM4J解析xml文档
		InputStream input = this.getClass().getClassLoader().getResourceAsStream("china.xml");
		SAXReader reader = new SAXReader();
		try {
			Document doc = reader.read(input);
			// xpath查询所有province元素的name属性
			List<Attribute> provinceNameAttributeList = doc.selectNodes("//province/@name");
			// 用来装载所有name属性值
			List<String> provinceNames = new ArrayList<String>();
			// 遍历每个属性,获取属性名称,添加到list中
			for(Attribute proAttr : provinceNameAttributeList) {
				provinceNames.add(proAttr.getValue());
			}
//			System.out.println(provinceNames);
			// 把list转换成字符串
			String str = provinceNames.toString();
			// 把字符串前后中的[]去除发送给客户端
			response.getWriter().print(str.substring(1, str.length()-1));
		} catch (DocumentException e) {
			throw new RuntimeException(e);
		}
	}
}</span>


      CityServlet.java:

<span style="font-size:18px;">public class CityServlet extends HttpServlet {
	public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		// 注意,这里内容类型必须是text/xml,不然客户端得到的就不是xml文档对象,而是字符串了。
		response.setContentType("text/xml;charset=utf-8");
		// 获取省份参数
		String provinceName = request.getParameter("provinceName");
		
		InputStream input = this.getClass().getClassLoader().getResourceAsStream("china.xml");
		SAXReader reader = new SAXReader();
		try {
			Document doc = reader.read(input);
			// 查询指定省份名称的<province>元素
			Element provinceElement = (Element)doc.selectSingleNode("//province[@name='" + provinceName + "']");
//			System.out.println(provinceElement.asXML());
			// 把元素转换成字符串发送给客户端
			response.getWriter().print(provinceElement.asXML());
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}</span>


    客户端(解释放在注释中):

       在打开select.jsp页面时就向服务器请求所有省份的名称,添加到<select name=”province”>元素中。

       给<select name=”province”>元素添加onchange事件监听,内容为向服务器发送请求,得到XML文档:<province>元素,然后解析它,添加到<select name=”city”>中。


<span style="font-size:18px;">// 文档加载完成后
// 加载所有省份名称
window.onload = function() {
	//请求服务器,加载所有省名称到<select>中
	//1. ajax四步
	var xmlHttp = createXMLHttpRequest();
	xmlHttp.onreadystatechange = callback;//服务器响应完成后执行callback函数
	xmlHttp.open("GET", "/ajaxdemo1/ProvinceServlet", true);//向服务器发送GET请求
	xmlHttp.send(null);//发送请求
};
// 本方法获取服务器响应的所有省份的名称
function callback() {
	if(this.readyState == 4 && this.status == 200) {
		// 把服务器响应的省份名称,使用逗号分割成字符串数组
		var provinceNameArray = this.responseText.split(", ");
		// 遍历每个省份名称,使用每个省份名称创建<option>元素,添加到province的<select>中
		for(var i = 0; i < provinceNameArray.length; i++) {
			addProvinceOption(provinceNameArray[i]);
		}
		// 为province的<select>元素添加onchange事件监听
		document.getElementById("province").onchange = loadCities;
	}
}
// 本函数在province的<select>元素发送变化时执行!
// 本函数会使用当前选中的省份名称为参数,向服务器发送请求,获取当前省份下的所有城市!
function loadCities() {
	var proName = this.value;//获取<select>选择的省份名称
	/*
	AJAX4步
	*/
	var xmlHttp = createXMLHttpRequest();//创建异常对象
	// 指定回调函数
	xmlHttp.onreadystatechange = function() {
		if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
			// 得到服务器响应的xml文档对象
			var doc = xmlHttp.responseXML;//注意,这里使用的是resopnseXML属性,不是resopnseText
			// 获取文档中所有city元素
			var cityElementList = doc.getElementsByTagName("city");
			// 获取html元素:city的<select>
			var citySelect = document.getElementById("city");
			// 删除city的<select>元素的所有子元素
			removeChildNodes(citySelect);
			
			// 创建<option>元素,指定文本内容为“请选择”
			var qxzOption = document.createElement("option");
			var textNode = document.createTextNode("===请选择===");
			qxzOption.appendChild(textNode);
			// 把"请选择"这个<option>添加到<select>元素中
			citySelect.appendChild(qxzOption);
			
			// 循环遍历每个服务器端响应的每个<city>元素
			for(var i = 0; i < cityElementList.length; i++) {
				var cityEle = cityElementList[i];
				var cityName = null;
				// 获取<city>元素的文本内容!处理浏览器差异!
				if(window.addEventListener) {
					cityName = cityEle.textContent;
				} else {
					cityName = cityEle.text;
				}
				// 使用城市名称创建<option>,并添加到<select>元素中
				addCityOption(cityName);
			}
		}
	};
	xmlHttp.open("POST", "/ajaxdemo1/CityServlet", true);//打开与服务器的连接
	// 因为是POST请求,所以要设置Content-Type请求头
	xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	// 参数为当前选中的省份名称
	xmlHttp.send("provinceName=" + proName);	
}
// 使用proName创建<option>元素添加到<select>元素中
function addProvinceOption(proName) {
	var option = document.createElement("option");//创建<option>元素
	var textNode = document.createTextNode(proName);//使用省份名称创建文本节点
	option.appendChild(textNode);//把省份名称的文本节点添加到<option>元素中
	option.setAttribute("value", proName);//使用省份名称来设置<option>元素的value属性
	document.getElementById("province").appendChild(option);//把<option>元素添加到<select>元素中 
}
// 本函数用来创建城市的<option>,并添加到<select>元素中
function addCityOption(cityName) {
	var citySelect = document.getElementById("city");//获取id为city的<select>
	var cityOption = document.createElement("option");//创建<option>元素
	var textNode = document.createTextNode(cityName);//使用城市名称创建文本节点
	cityOption.appendChild(textNode);//把文本节点添加到<option>元素中
	cityOption.setAttribute("value", cityName);//设置<option>元素的value属性为城市名称
	citySelect.appendChild(cityOption);//把<option>元素添加到<select>元素中
}
//删除指定元素的所有子元素
function removeChildNodes(ele) {
	var nodes = ele.childNodes;//获取当前元素的所有子元素集合
	while(nodes.length > 0) {//遍历所有子元素
		ele.removeChild(nodes[0]);//删除子元素
	}
}</span>


  分享:关于XPATH的使用讲解链接(请点这里),其中的几张图非常好。


你可能感兴趣的:(Ajax,Ajax,Ajax,表单,xpath,post请求,Get请求)