在使用XMLHttpRequest 对象发送请求和处理相应之前,必须先用JavaScript创建一个XMLHttpRequest对象。由于XMLHttpRequest不是一个W3C标准,所以可以先用多种方法使用jS创建XMLHttpRequest对象。IE把XMLHttpRequest实现为一个ActiveX对象,其他浏览器把它实现为本地javascript对象。因而使用activex或本地javascript创建XMLHttpRequest对象。
XMLHttpRequest对象
一:如何创建XMLHttpRequest对象
程序清单一:
var xmlHttp;
function createXMLHttpRequest()
{
if(window.ActiveXObject){
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}else
{
xmlHttp=new XMLHttpRequest();
}
}
首先创建一个全局作用域变量xmlHttp来保存这个对象的引用。createXMLHttpRequest方法完成创建实例的具体工作。这个方法中只有简单的分支逻辑来确定如何创建对象。
对window.ActiveXObject的调用会返回一个对象,也可能返回NULL,从而判断不同的浏览器。从而js的兼容性。
二,方法和属性
方法 | 描述 |
abort() | 停止当前请求 |
getAllResponseHeaders() | 把HTTP请求的所有响应首部作为键/值对返回 |
open(“method”,“url”) | 建立对服务器的调用。method参数可以是GET POST PUT |
send(content) | 向服务器发送请求 |
setRequestHeader("header","value"); | 把首部设定为所提供的值 |
|
|
三交互实例
1,一个客户端事件触发一个AJAX事件。从简单的onchange事件到某个特定的用户动作,很多这样的事件都触发AJAX事件:如
<input type="text" d="email" name="email" οnblur="validateEmail()">
2,创建XMLHttpRequest对象的一个实例。使用open()方法建立调用,并设置URL以及所希望的HTTP方法。请求实际上通过一个send()方法调用触发。肯的代码
var xmlHttp;
function validateEmail(){
var email=document.getElementById("email");
var url="validate?email"+escape(email.value);
if(window.ActiveXObject){
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}else if(window.XMLHttpRequest){
xmlHttp=new XMLHttpRequest();
}
xmlHttp.open("GET", url);
xmlHttp.onreadystatechange=callback;
xmlHttp.send(null);
}
3,向服务器做出请求
4,服务器帮你做想做的事情
5请求返回服务器
6.在这个实例中,XMLHttpRequest对象配置为处理返回时要调用callback()函数,这个函数会检查XMLHttpRequest对象的readyState属性,然后查看服务器的返回状态码
function callback()
{
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
//do something here
}
}
}
四:GET和POST
在许多情况下,浏览器和服务器会限制URL的长度。一般来说,可以使用GET从服务器获取数据,换句话,要避免使用GET调用改变服务器上的状态
一般地,当改变服务器的状态时用POST方法,不同于GET,需要设置XMLhttpRequest对象的Content-Type首部
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
五,远程脚本
远程脚本是一种远程过程中调用的类型。可以像正常的web应用一样与服务器交互,但不用刷新整个页面。
六,如何发送简单的请求
最简单的请求是,不以查询或提交表单数据的形式向服务器发送任何信息。在实际中,往往想要发送信息
1,为得到XMLHttpRequest对象的一个引用,可以创建一个新的实例,也可以访问包含有XMLHttpRequest实例的一个变量。
2,告诉XMLHttpRequest对象,哪个函数会处理XMLHttpRequest对象状态的改变,为此要把对象的onreadystatechange属性设置为指向javascript函数的指针。
3,指定请求的属性。XMLHttpRequest对象的open()方法把请求发送的请求。open()方法取三个参数:一个是指示所用的方法的串,一个是表示目标资源URL的串:一个是Boolean值,指示请求是否是异步的。
4,将请求发送给服务器,XMLHttpRequest对象的send()方法把请求发送到指定的目标资源,send()方法把请求发送到指定的目标资源,send()方法接受一个参数,通常是一个串或一个DOM对象,这个参数作为请求体的一部分发送到目标URL。当向send()方法提供参数时,要确保open()中指定的方法是post.如果没有数据作为请求体的一部分被发送,则使用null;
这些步骤很直观,你需要XMLhttpRequest对象的一个实例,要告诉他如果状态有变化该怎么做,还要告诉它哪里发送请求以及如何发送请求,最后还需要指导XMLHttpRequest发送请求。
对于XMLHttpRequest对象,onreadystatechange属性存储了回调函数的指针,当XMLHttpRequest对象的内部状态发送变化时,就会回调这个函数。当进行了异步调用,请求就会发出脚本会立即处理。一旦发出了请求,对象readyStatus属性会经过几个变化。尽管针对任何状态都可以做一些处理,不过是最关心的是服务器响应结束是的状态。通过回调函数,就可以有效的告诉XMLHttpRequest对象:‘’只要响应到来,就调用这个函数来处理响应“
简单的请求实例
这是一个很小的html页面,只有一个按钮。点击这个按钮会初始化一个发至服务器的异步请求。服务器将返回一个简单的静态文本文件作为响应。在处理这个响应时,会在一个警告窗口中显示静态文本的内容。
<!DOCTYPE html>
<html>
<head>
<title>simpleRequest.html</title>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
<script type="text/javascript">
var xmlHttp;
function createXMLHttpRequest(){
if(window.ActiveXObject){
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}else if(window.XMLHttpRequest){
xmlHttp=new XMLHttpRequest();
}
}
function startRequest(){
createXMLHttpRequest();
xmlHttp.onreadystatechange=handleStateChange;
xmlHttp.open("GET","simpleResponse.xml", true);
xmlHttp.send(null);
}
function handleStateChange(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200)
{
alert("The server replied with:"+xmlHttp.responseText);
}
}
}
</script>
</head>
<body>
<form action="#"></form>
<input type="button" value="Start Basic Request" οnclick="startRequest();" />
</body>
</html>
点击HTML文件的按钮会出现一个警告框,其中显示simpleResponse.xml文件的内容。
对服务器的请求是异步发送的,因此浏览器可以继续响应用户输入,同时在后台等待服务器的响应。如果选择同步操作,而且倘若服务器的响应要花几秒才能到达,浏览器就会表现的很迟钝,在等待期间不能响应用户的输入。
关于安全
XMLHttpRequest对象要受制于浏览器的安全沙箱,XMLHttpRequest对象请求的所有资源都必须与调用脚本在同一域内。这个安全限制使得XMLhtt对象不能请求脚本所在域之外的资源。
七,DOM LEVEL 3加载和保存规约
平台兼容性问题,不做具体讨论
八,DOM
DOM是个W3C的规约,可以以一种独立域平台和语言的方式访问和修改文档的内容和结构。话句话,就是表示和处理一个HTML或XML文档的方法。
DOM实际上是以面向对象方式描述的对象模型。DOM定义了表示和修改文档所需的对象,这些对象的行为和属性,以及对象之间的关系。可以把DOM认为是页面上数据和结构的一个树形表示,不过页面当然可能不是以树的方式具体实现。
处理服务器的响应
XMLHttpRequest对象提供了两个可以用来访问服务器响应的属性。第一个属性responseText将响应提供为一个串,第二个属性responseXML将响应提供为一个XML对象。一个简单的用例就很适合按简单文本来获取响应,如将响应显示在警告框中,或则响应只能指示成功还是失败的词。
一,使用innerHTML属性创建动态内容
如果将服务器响应作为简单文本来访问,则灵活性欠佳。简单文本没有结构,很难用javascript进行逻辑性的表述,而且要想动态的生成也页面内容很困难。
如果结和使用HTML元素的innerHTML属性,responseText属性就会变得非常有用。innerhTML属性是一个非标准的属性,。通过结合使用responseText和innerhTML,服务器就能生成HTML内容。下面是个例子
1,点击search按钮,调用startRequest函数,它先调用createXMLHttpRequest函数来初始化XMLHttpRequest对象的一个实例
2startRequest函数将回调函数来设置为handleStateChange函数
3startRequest函数使用open()方法来设置请求方法(GET)及请求目标,并且设置为异步的完成请求
4,使用XMLHttpRequest对象send()方法发送请求
5,XMLHttpRequest对象的内部状态每次有变化时,都会调用handleStartRequest函数。一旦接收响应,div元素的innerhTML属性将使用XMLHttpRequest对象responseText属性设置。
<!DOCTYPE html>
<html>
<head>
<title>innerHtml.html</title>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
<script type="text/javascript">
var xmlHttp;
function createXMLHttpRequest(){
if(window.ActiveXObject){
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}else if(window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
}
function startRequest(){
createXMLHttpRequest();
xmlHttp.onreadystatechange=handleStateChange;
xmlHttp.open("GET","innerHtml.xml",true);
xmlHttp.send(null);
}
function handleStateChange(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
document.getElementById("result").innerHTML=xmlHttp.responseText;
}
}
}
</script>
</head>
<body>
<form action="#">
<input type="button" value="search for today's activitys" οnclick="startRequest();"/>
</form>
<div id="result"></div>
</body>
</html>
innerHtml.xml
<?xml version="1.0" encoding="UTF-8"?>
<table border="1">
<tbody>
<tr>
<th>Activity Name</th>
<th>Location</th>
<th>Time</th>
</tr>
<tr>
<th>Waterskiing</th>
<th>DOCK#1</th>
<th>9:00 AM</th>
</tr>
<tr>
<th>Hiking</th>
<th>Trail 3</th>
<th>9:00 PM</th>
</tr>
</tbody>
</table>
使用responseText和innerHTML可以大大简化向页面增加动态内容的工作。innerHTML属性不是HTML元素的标准属性,所以与标准兼容的浏览器不一定提供这个属性的实现。二,将响应解析为XML
服务器不一定按XML格式发送响应。只要content-Type响应首部正确的设置为text/plain,将响应作为简单文本传送是完全可能的。复杂的数据结构很适合用XML格式发送。对于导航XML文档以及修改XML文档的结构和内容,当前的浏览器提供了很好的支持。
DOM是面向HTML和XML文档的API,为文档提供了结构化表示,并定义了如何通过脚本访问文档结构。
Javascript用于访问和处理DOM语言
程序清单三:服务器返回的州名列表
在浏览器会产生有两个按钮的HTML文档。点击第一个按钮,将从服务器加载XML文档,然后在警告框里显示文档中所有的州。点击第二个也会从服务器加载XML文档,不过是只在警告框里显示北部的各个州。
<!DOCTYPE html>
<html>
<head>
<title>parseXML.html</title>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
<script type="text/javascript">
var xmlHttp;
var requestType="";
function createXMLHttpRequest(){
if(window.ActiveXObject)
{
xmlHttp=new ActiveXObject("Microsofe.XMLHTTP");
}else if(window.XMLHttpRequest)
{
xmlHttp=new XMLHttpRequest();
}
}
function startRequest(requestedList)
{
requestType=requestedList;
createXMLHttpRequest();
xmlHttp.onreadystatechange=handleStateChange;
xmlHttp.open("GET", "parseXML.xml",true);
xmlHttp.send(null);
}
function handleStateChange(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
if(requestType=="north"){
listNorthStates();
}else if(requestType=="all"){
listALLStates();
}
}
}
}
function listNorthStates(){
var xmlDoc=xmlHttp.responseXML;
var northNode=xmlDoc.getElementByTagName("north")[0];
// var out="Northern States";
var northStates=northNode.getElementByTagName("state");
outputList("Northern States",northStates);
}
function listAllStates(){
var xmlDoc=xmlHttp.responseXML;
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<status.length;i++){
currentState=states[i];
out=out+"\n-"+currentState.childNode[0].nodeValue;
}
alert(out);
}
</script>
</head>
<body>
<form action="#">
<input type="button" value="View All Listed States" οnclick="startRequest('all');" />
<input type="button" value="View north Listed States" οnclick="startRequest('north');" />
</form>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<xml-body>
<states>
<north>
<state>Minmesota</state>
<state>Minmesota</state>
<state>Minmesota</state>
</north>
<east>
<state>Minmesota</state>
<state>Minmesota</state>
<state>Minmesota</state>
</east>
<south>
<state>Minmesota</state>
<state>Minmesota</state>
<state>Minmesota</state>
</south>
<west>
<state>Minmesota</state>
<state>Minmesota</state>
<state>Minmesota</state>
</west>
</states>
</xml-body>
仔细看一下ListAllStatus函数。它首先创建了一个局部变量,名为xmlDoc,并将这个变量初始化设置为服务器返回的XML文档,这个文档是使用XMLHttpRequest对象的responseXML属性得到的。利用XML文档的getElementByTageName方法获取文档中所有标记为state的元素。getElementByTagName方法返回了包含所有state元素的数组,这个数组将赋值给名为allStatus的局部变量。
三,使用W3C DOM动态编辑页面
属性/方法 | 描述 |
document.createElement(tagName) | 文档对象上的createElement方法可以创建由tagname指定的元素 |
document.createTextNode(text) | 文档对象的createTextNode方法创建包含静态文本的节点 |
<element>.appendChild(childNode) | appendChild方法将指定的节点增加到当前元素的子节点列表 |
getAttribute(name) | |
四,发送请求参数
要充分发挥Ajax技术的强大功能,这要求你向服务器发送一些上下文数据。假设有一个输入表单,其中包含需要输入邮件地址的部分。根据用户输入的ZIP编码,可以使用Ajax技术预填相应的城市名。当然,要想知道ZIP编码对应的城市,服务器需要知道用户输入的ZIP编码。
GET方法把值作为名./值对应放在请求URL中传递。资源URL的最后有一个(?),问号后面就是名/值对。
http://localhost/yourApp?firstName=Adam&middleName=Christ
服务器知道如何获取URL中的命名参数。当前大多数服务器端编程环境都提供了简单的API,使得很容易访问命名参数。
采用POST方法向服务器发送命名参数时,与采用GET方法差不多,区别是POST方法将参数串放在请求体中发送,而GET方法是将参数追加到URL中发送。
下面程序展示了如何向服务器发送请求参数
<!DOCTYPE html>
<html>
<head>
<title>getAndPostExample.html</title>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
<script type="text/javascript">
var xmlHttp;
function createXMLHttpRequest(){
if(window.ActiveXObject){
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
else if(window.XMLHttpRequest){
xmlHttp=new XMLHttpRequest();
}
}
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 queryString="GetAndPostExample?";
queryString=queryString+createQueryString()
+"&timeStamp="+new Date().getTime();
xmlHttp.onreadystatechange=handleStateChange;
xmlHttp.open("GET",queryString, true);
xmlHttp.send(null);
}
function doRequestUsingPOST(){
createXMLHttpRequest();
var url="GetAndPOSTExample?timeStamp="+new Date().getTime();
var queryString=createQueryString();
xmlHttp.open("POST", url, true);
xmlHttp.onreadystatechange=handleStateChange;
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
xmlHttp.send(queryString);
}
function handleStateChange(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
parseResults();
}
}
}
function parseResults(){
var responseDiv=document.getElementById("serverResponse");
if(responseDiv.hasChildNodes()){
responseDiv.removeChild(responseDiv.childNodes[0]);
}
var responseText=document.createTextNode(xmlHttp.responseText);
responseDiv.appendChild(responseText);
}
</script>
</head>
<body>
Enter your first name,middle name,and birthday <br>
<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>
<form action="#">
<input type="button" value="Send parameters using GET" οnclick="doRequestUsingGET();">
<input type="button" value="Send parameters using POST" οnclick="doRequestUsingPOST();">
</form>
<br>
<h2>Server Response:</h2>
<div id="serverResponse"></div>
</body>
</html>
package ajax;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GetAndPostExample extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
protected void processRequest(HttpServletRequest request,
HttpServletResponse response,String method)throws ServletException,IOException{
response.setContentType("text.html");
String firstName=request.getParameter("firstname");
String middleName=request.getParameter("middleName");
String birthday=request.getParameter("birthday");
String responseText="Hello"+firstName+" "+middleName+".Your birthday is"
+birthday+"."+"[method:"+method+"]";
PrintWriter out=response.getWriter();
out.print(responseText);
out.close();
}
protected void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
processRequest(request,response,"GET");
}
protected void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
processRequest(request,response,"POST");
}
}
package ajax;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GetAndPostExample extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
protected void processRequest(HttpServletRequest request,
HttpServletResponse response,String method)throws ServletException,IOException{
response.setContentType("text.html");
String firstName=request.getParameter("firstname");
String middleName=request.getParameter("middleName");
String birthday=request.getParameter("birthday");
String responseText="Hello"+firstName+" "+middleName+".Your birthday is"
+birthday+"."+"[method:"+method+"]";
PrintWriter out=response.getWriter();
out.print(responseText);
out.close();
}
protected void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
processRequest(request,response,"GET");
}
protected void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
processRequest(request,response,"POST");
}
}
这个例子使用了java servlet处理请求。java servlet必须定义doGet方法和doPost方法。processResponse方法先把响应的内容类型设置为text/html,尽管在这个例子中没用到XML。通过getParameter方法从request对象获取三个三个输入字段。
四,请求参数作为XML发送
将模型化的变化作为XML发送到服务器。可以把XML作为请求体的一部分发送到服务器,这与post请求中将查询字符串作为请求体的一部分差不多。服务器读到XML,处理。
下例选择框中的选中的项作为XML发送到服务器
<!DOCTYPE html>
<html>
<head>
<title>postingXML.html</title>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
<script type="text/javascript">
var xmlHttp;
function createXMLHttpRequest(){
if(window.ActiveXObject)
{
xmlHttp=new ActiveXObject();
}else if(window.XMLHttpRequest){
xmlHttp=new XMLHttpRequest();
}
}
function createXML(){
var xml="<pets>";
var options=document.getElementById("petTypes").childNodes;
var option=null;
for(var i=0;i<options.length;i++){
option=options[i];
if(option.selected){
xml=xml+"<type>"+option.value+"<\/type>";
}
}
xml=xml+"<\/pets>";
return xml;
}
function sendPetTypes(){
createXMLHttpRequest();
var xml=createXML();
var url="PostingXMLExample?timeStamp="+new Date().getTime();
xmlHttp.open("POST", url, true);
xmlHttp.onreadystatechange=handleStateChange;
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
xmlHttp.send(xml);
}
function handleStateChange(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
parseResults();
}
}
}
function parseResults(){
var responseDiv=document.getElementById("serverResponse");
if(responseDiv.hasChildNodes()){
responseDiv.removeChild(responseDiv.childNodes[0]);
}
var responseText=document.createTextNode(xmlHttp.responseText);
responseDiv.appendChild(responseText);
}
</script>
</head>
<body>
<h1>Select the types of pets in your home:</h1>
<form action="#">
<select id="petTypes" size="6" multiple="true">
<option value="cats">Cats</option>
<option value="dogs">Dogs</option>
<option value="fish">Fish</option>
<option value="birds">Birds</option>
<option value="hamster">Hamster</option>
</select>
<br>
<br>
<input type="button" value="Submit Pets" οnclick="sendPetTypes();" />
</form>
<h2>Server Respon
<!DOCTYPE html>
<html>
<head>
<title>postingXML.html</title>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
<script type="text/javascript">
var xmlHttp;
function createXMLHttpRequest(){
if(window.ActiveXObject)
{
xmlHttp=new ActiveXObject();
}else if(window.XMLHttpRequest){
xmlHttp=new XMLHttpRequest();
}
}
function createXML(){
var xml="<pets>";
var options=document.getElementById("petTypes").childNodes;
var option=null;
for(var i=0;i<options.length;i++){
option=options[i];
if(option.selected){
xml=xml+"<type>"+option.value+"<\/type>";
}
}
xml=xml+"<\/pets>";
return xml;
}
function sendPetTypes(){
createXMLHttpRequest();
var xml=createXML();
var url="PostingXMLExample?timeStamp="+new Date().getTime();
xmlHttp.open("POST", url, true);
xmlHttp.onreadystatechange=handleStateChange;
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
xmlHttp.send(xml);
}
function handleStateChange(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
parseResults();
}
}
}
function parseResults(){
var responseDiv=document.getElementById("serverResponse");
if(responseDiv.hasChildNodes()){
responseDiv.removeChild(responseDiv.childNodes[0]);
}
var responseText=document.createTextNode(xmlHttp.responseText);
responseDiv.appendChild(responseText);
}
</script>
</head>
<body>
<h1>Select the types of pets in your home:</h1>
<form action="#">
<select id="petTypes" size="6" multiple="true">
<option value="cats">Cats</option>
<option value="dogs">Dogs</option>
<option value="fish">Fish</option>
<option value="birds">Birds</option>
<option value="hamster">Hamster</option>
</select>
<br>
<br>
<input type="button" value="Submit Pets" οnclick="sendPetTypes();" />
</form>
<h2>Server Response:</h2>
<div id="sererResponse"></div>
</body>
</html>