Ajax Hacks-hack7接收JSON格式的数据

80酷酷网    80kuku.com

  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:



脚本标记引入的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");

<

分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: