你的位置:首页 > Java教程

[Java教程]【高级功能】使用 Ajax(续)


1. 准备向服务器发送数据

Ajax 最常见的一大用途是向服务器发送数据。最典型的情况是从 客户端发送表单数据,即用户在form元素所含的各个 input 元素里输入的值。下面代码展示了一张简单的表单:

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <title>基本表单</title>  <style>    .table{display: table;}    .row{display: table-row;}    .cell{display: table-cell;padding: 5px;}    .lable{text-align: right;}  </style></head><body><form id="fruitform" method="post" action="http://127.0.0.1:8080/form">  <div class="lable">    <div class="row">      <div class="cell lable">Apples:</div>      <div class="cell"><input name="apples" value="5" /></div>    </div>    <div class="row">      <div class="cell lable">Bananas:</div>      <div class="cell"><input name="bananas" value="2" /></div>    </div>    <div class="row">      <div class="cell lable">Cherries:</div>      <div class="cell"><input name="cherries" value="20" /></div>    </div>    <div class="row">      <div class="cell lable">Total:</div>      <div id="results" class="cell">0 items</div>    </div>  </div>  <button id="submit" type="submit">Submit Form</button></form></body></html>

这个例子中的表单包含三个input元素和一个提交button 。这些input元素让用户可以指定三种不同的说过各自要订购多少,button则会将表单提交给服务器。

 

1.1 定义服务器

显而易见,这里需要为这些示例创建处理请求的服务器。这里再一次使用Node.js,原因主要是它很简单,而且用的是Javascript。新建 fruitcalc.js脚本文件如下:

 

var http = require('http');var querystring = require('querystring');function writeResponse(res,data){  var total = 0;  for(fruit in data){    total += Number(data[fruit]);  }  res.writeHead(200,"OK",{    "Content-Type":"text/html",    "Access-Control-Allow-Origin":"http://localhost:63342"  });  res.write('<html><head><title>Fruit Total</title></head><body>');  res.write('<p>'+total+' item ordered</p></body></html>');  res.end();}http.createServer(function(req,res){  console.log("[200] "+req.method+" to "+req.url);  if(req.method == "OPTIONS"){    res.writeHead(200,"OK",{      "Access-Control-Allow-Header":"Content-Type",      "Access-Control-Allow-Methods":"*",      "Access-Control-Allow-Origin":"*"    });    res.end();  }else if(req.url == '/form'&& req.method == 'POST'){    var dataObj = new Object();    var contentType = req.headers["content-type"];    var fullBody = '';        if(contentType){      if(contentType.indexOf("application/x-www-form-urlencode") > -1){        req.on('data',function(chunk){          fullBody += chunk.toString();        });        req.on('end',function(){          var dBody = querystring.parse(fullBody);          dataObj.apples = dBody["apples"];          dataObj.bananas = dBody["bananas"];          dataObj.cherries = dBody["cherries"];          writeResponse(res,dataObj);        });      }else if(contentType.indexOf("application/json") > -1){        req.on('data',function(chunk){          fullBody += chunk.toString();        });        req.on('end',function(){          dataObj = JSON.parse(fullBody);          writeResponse(res,dataObj);        });      }    }  }}).listen(8080);

脚本中高亮部分:writeResponse函数。这个函数会在提取请求的表单值之后调用,它负责生产对浏览器的响应。当前,这个函数会创建简单的HTML文档,效果如下:

这个响应很简单,实现效果是让服务器计算出了用户通过form中各个input元素所订购的水果总数。服务器得端脚本的其余部分负责解码客户端用Ajax发送的各种可能数据格式。

 

1.2 理解问题所在

上面的图片清楚的描述了想要用Ajax解决的问题。

当提交表单后,浏览器会在新的页面显示结果。这意味着两点:

* 用户必须等待服务器处理数据并生成响应;

* 所有文档上下文信息都丢失了,因为结果是作为新文档进行显示的。

这就是应用Ajax的理想情形了。可以异步生成请求,这样用户就能在表单被处理时继续与文档进行交互。

 

2. 发送表单

向服务器发送数据的最基本方式是自己收集并格式化它。下面代码展示了添加到前面的HTML文档 example.html 的一段脚本。用的就是这种方式:

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <title>手动收集和发送数据</title>  <style>    .table{display: table;}    .row{display: table-row;}    .cell{display: table-cell;padding: 5px;}    .lable{text-align: right;}  </style></head><body><form id="fruitform" method="post" action="http://127.0.0.1:8080/form">  <div class="lable">    <div class="row">      <div class="cell lable">Apples:</div>      <div class="cell"><input name="apples" value="5" /></div>    </div>    <div class="row">      <div class="cell lable">Bananas:</div>      <div class="cell"><input name="bananas" value="2" /></div>    </div>    <div class="row">      <div class="cell lable">Cherries:</div>      <div class="cell"><input name="cherries" value="20" /></div>    </div>    <div class="row">      <div class="cell lable">Total:</div>      <div id="results" class="cell">0 items</div>    </div>  </div>  <button id="submit" type="submit">Submit Form</button></form><script>  document.getElementById("submit").onclick = handleButtonPress;  var httpRequest;  function handleButtonPress(e){    //对表单里的button元素而言,其默认行为是用常规的非Ajax方式提交表单。这里不想让他发生,所以调用了preventDefault方法    e.preventDefault();    var form = document.getElementById("fruitform");    //收集并格式化各个input的值    var formData ="";    var inputElements = document.getElementsByTagName("input");    for (var i = 0; i < inputElements.length; i++){      formData += inputElements[i].name + "=" + inputElements[i].value +"&";    }    httpRequest = new = handleResponse;    //数据必须通过POST方法发送给服务器,并读取了HTMLFormElement的action属性获得了请求需要发送的URL    httpRequest.open("POST",form.action);    //添加标头来告诉服务器准备接受的数据格式    httpRequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded');    //把想要发送给服务器的字符串作为参数传递给send方法    httpRequest.send(formData);  }  function handleResponse(){    if(httpRequest.readyState == 4 && httpRequest.status == 200){      document.getElementById("results").innerHTML = httpRequest.responseText;    }  }</script></body></html>

 

效果图如下:

服务器响应表单提交后返回的HTML文档会显示在同一页,而且该请求是异步执行的。

 

3. 使用FormData对象发送表单数据

另一种更简洁的表单收集方式是使用一个FormData对象,它是在

3.1 创建 FormData 对象

loading... 代码问题,正在解决

 

4. 发送JSON数据

Ajax不止用来发送表单数据,几乎可以发送任何数据,包括JavaScript对象表示法(JavaScript Object Notation,JSON)数据,而它几乎已经成为一种流行的数据格式了。Ajax扎根于

JSON经常被称为

以下是一个简单的JavaScript对象用JSON表达的例子:

{"bananas":"2","apples":"5","cherries":"20"}

这个对象有三个属性:bananas、apples和cherries。这些属性的值分别是2、5和20。

JSON的功能不如

<script>  document.getElementById("submit").onclick = handleButtonPress;  var httpRequest;  function handleButtonPress(e){    e.preventDefault();    var form = document.getElementById("fruitform");    var formData = new Object();    var inputElements = document.getElementsByTagName("input");    for(var i=0;i<inputElements.length;i++){      formData[inputElements[i].name] = inputElements[i].value;    }    httpRequest = new = handleResponse;    httpRequest.open("POST",form.action);    httpRequest.setRequestHeader("Content-Type","application/json");    httpRequest.send(JSON.stringify(formData));  }  function handleResponse(){    if(httpRequest.readyState == 4 && httpRequest.status == 200){      document.getElementById("results").innerHTML = httpRequest.responseText;    }  }</script>

这段脚本,创建了一个新的Object,并定义了一些属性来对应表单内各个input元素的name属性值。可以使用任何数据,但 input元素很方便,而且能和之前的例子保持一致。

为了告诉服务器正在发送JSON数据,把请求的Content-Type标头设为 application/json,就像这样:

httpRequest.setRequestHeader("Content-Type","application/json");

用JSON对象和JSON格式进行相互的转换。(大多数浏览器能直接支持这个对象,但也可以用下面的网址里的脚本来给旧版的浏览器添加同样的功能:https://github.com/douglascrockford/JSON-js/blob/master/json2.js )JSON对象提供了两个方法:

在上面的例子中,使用了stringify方法,然后把结果传递给

 

5. 发送文件

可以使用FormData 对象和type 属性为 file 的input 元素向服务器发送文件。当表单提交时,FormData对象会自动确保用户选择的文件内容与其他的表单值一同上传。下面的例子展示了如何以这种方式使用FormData对象。

 

(待续。。。)