ajax|js|数据
Ajax Hacks-hack7接收JSON格式的数据
怎样才能使用Ajax从服务器接收js对象数据呢?你可以使用一种叫javascript 对象符号的格式接收数据。本hack讲述用户输入信息,从服务器得到JSON格式的响应数据。
JSON很普通而直观,这也许是许多开发者喜欢使用的原因吧。一个例子就是,服务器程序从服务器得到信息,然后以JSON格式返回给web页面。JSON格式的数据描述如下:
左大括号“{”
一个或多个属性名,以冒号隔开的对应的值,以逗号隔开的属性/值对。
右大括号 “}”
每个属性的值可以是:
简单的字符串,例如 “hello”
数组,例如 [1,2,3,4]
数字
true, false, 或 null
其他对象,组合的,或者对象中还有对象。
详细信息请访问:http://www.json.org
在JavaScript中,对象的格式是严格的。作为一个例子,在hack2中的请求信息改写为JSON格式为:
{
firstname:“Bruce”,
lastname:“Perry”,
gender:“M”,
country:“USA”
}
Magic JSON
在这一部分里,我们还使用hack2中的例子,只是处理的数据是JSON格式的数据。页面的html代码如下:
“http://www.w3.org/TR/1999/REC-html401–19991224/strict.dtd”>
A Few Facts About Yourself...
javascript:void%200>
First name:
Last name:
Gender:
Country of origin:
Send Data
脚本标记引入的js文件为hack5.js。JS将用户输入的值发送到服务器;这些都已经在hack2等节介绍过了,这里就不详细解释了。
当js处理返回值的时候,需要注意XSS攻击。这对于那些使用eval或其他相关函数来说是一个潜在的威胁。
作为一个相应的措施,在函数eval使用responseText之前,客户端代码可以过滤并检测返回值(即,通过检查XMLHttpRequest responseText属性)
下面是hack的代码,我们将着重关注处理返回值部分的代码:
var request;
var queryString; //保存POSTed 数据
function sendData( ){
setQueryString( );
url=“http://www.parkerriver.com/s/json”;
httpRequest(“POST”,url,true);
}
//event handler for XMLHttpRequest
function handleJson( ){
if(request.readyState == 4){
if(request.status == 200){
var resp = request.responseText;
var func = new Function(“return ”+resp);
var objt = func( );
var div = document.getElementById(“json”;
stylizeDiv(resp,div);
div = document.getElementById(“props”;
div.innerHTML=”
In object form...
"+
”
Properties
firstname= "+
objt.firstname "
lastname="
objt.lastname+ ”
gender="+
objt.gender+ ”
country="+
objt.country;
} else {
alert(“A problem occurred with communicating between ”+
“the XMLHttpRequest object and the server program.”;
}
}//end outer if
}
/* Initialize a request object that is already constructed */
function initReq(reqType,url,bool){
/* Specify the function that will handle the HTTP response */
request.onreadystatechange=handleJson;
request.open(reqType,url,bool);
request.setRequestHeader(“Content-Type”,
“application/x-www-form-urlencoded; charset=UTF-8”;
request.send(queryString);
}
/* Wrapper function for constructing a request object.
Parameters:
reqType: The HTTP request type, such as GET or POST.
url: The URL of the server program.
asynch: Whether to send the request asynchronously or not. */
function httpRequest(reqType,url,asynch){
//Snipped… See Hack #1 or #2
}
function setQueryString( ){
queryString=“”;
var frm = document.forms[0];
var numberElements = frm.elements.length;
for(var i = 0; i < numberElements; i++){
if(i < numberElements-1){
queryString = frm.elements[i].name"="+
encodeURIComponent(frm.elements[i].value)+“&”;
} else {
queryString = frm.elements[i].name"="+
encodeURIComponent(frm.elements[i].value);
}
}
}
function stylizeDiv(bdyTxt,div){
//reset DIV content
div.innerHTML=“ ”;
div.style.fontSize=“1.2em”;
div.style.backgroundColor=“yellow”;
div.appendChild(document.createTextNode(bdyTxt));
}
如本章前面的hack介绍的,initReq( )函数初始化request对象并向服务器发送HTTP请求。
事件处理函数将调用handleJson。相应数据的格式是JSON格式的字符串,而不是其他的XML或其他格式的数据。JS将这些返回文本看作string对象。因此,代码启动open步骤,在服务器返回值被转化成js对象之前。(btw,在本节里,服务器在发送响应数据之前会将请求参数重新格式化成JSON格式。)
这里没有包括特定的错误处理代码,而将其放在hack8中介绍。
在函数handleJson内的代码(高亮显示的部分),变量resp保存HTTP响应文本,js将其看作string。令人感兴趣的是函数的构造函数:
var func = new Function(“return ”+resp);
上面的代码将创建一个新的函数对象,以变量func命名。JavaScript编程者应当明白,大多数函数需要在代码中预先定义和声明,或者作为函数字面量创建。然而,在本例中,我们需要使用一个字符串动态的定义一个函数体,并且函数的构造子能提供完美的工具。
Thanks to this site for guidance on this code usage: http://www.jibbering.com/2002/4/httprequest.html.
另一种转换JSON字符串的方法是:
var resp = request.responseText;var obj = eval( “(” resp ")" );
在使用eval和一个数组的时候,也可以不必使用圆括号:
var resp = request.responseText;//resp 保存的如 “[1,2,3,4]”
var arrObject = eval(resp);
接下来的行用来创建一个返回一个对象字面量的寒暑,来描述服务器返回值。然后可以调用函数并使用返回对象来使用DOM编程在web页面动态显示服务器的返回结果。
var objt = func( );
var div = document.getElementById(“json”;
stylizeDiv(resp,div);
div = document.getElementById(“props”;
div.innerHTML=”
In object form...
Properties
firstname= "+
objt.firstname "
lastname="
objt.lastname+ ”
gender="+
objt.gender+ ”
country="+
objt.country;
objt变量来存储对象字面量。变量可从对象中取得,形如objt.firstname。
Figure 1-10 shows what the web page looks like after it has received a response.
Figure 1-10. Visualizing JavaScript properties is sweet!
在服务器端
java servlet用来处理请求。作为对服务器端有更多的了解,下面是该servlet的doPost方法的代码:
protected void doPost(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws
ServletException, IOException {
Map valMap = httpServletRequest.getParameterMap( );
StringBuffer body = new StringBuffer(“{\\n”;
if(valMap != null) {
String val=null;
String key = null;
Map.Entry me = null;
Set entries = valMap.entrySet( );
int size = entries.size( );
int counter=0;
for(Iterator iter= entries.iterator( );iter.hasNext( ) {
counter++;
me=(Map.Entry) iter.next( );
val= ((String[])me.getValue( ))[0];
key = (String) me.getKey( );
if(counter < size) {
body.append(key).append(“:\\““.append(val).append(“\\“,\\n”;
} else {
//remove comma for last entry
body.append(key).append(“:\\““.append(val).append(“\\“\\n”;
}
}
}
body.append(“}”;
AjaxUtil.sendText(httpServletResponse,body.toString( ));
}
AjaxUtil类发送HTTP响应以Content-Type of text/plain; charset=UTF-8的head。一些网站也有讨论使用Content-Type,但是,在这里,没有固定的格式。
AjaxUtil 类设置了HTTP响应的头格式:
response.setHeader("Cache-Control", "no-cache");
<