20.13.发送XML

问题
我想把XML数据发送给服务端脚本
解决办法
通过URLRequest实例把XML数据包装起来,用flash.net.sendToURL( ) 发送数据并忽略服务器的响应,用flash.net.navigateToURL( ) 发送数据并把服务器的响应显示在指定窗口,或者用URLLoader.load( ) 发送数据并处理服务器响应。
讨论
XML一般被用来在应用程序之间传输数据,因此创建XML并不仅仅用于Flash内部,一般都是从其他源中读取XML数据或创建XML数据并发送给其他应用程序。

这一节将讨论如何从Flash端发送XML数据给其他应用程序,实际上很多时候都是这样的,比如一个Flash游戏发送用户名和比分到服务器,或者发送XML数据给服务端触发某个功能模块对XML数据进行处理,这种处理被称为远程过程调用(RPC),如果规定都使用XML进行传递信息又被称为XML-RPC (看http://www.xmlrpc.com),所以你已经看到了,给服务器发送XML是很常用的。

第20.11节第19章所讲的,ActionScript 3.0 发送和读取数据的方法都在flash.net包中。以前的版本中XML 类专门有send( ) 和sendAndLoad( ) 方法用于发送XML 给服务器, 现在在ActionScript 3.0中必须用URLRequest对象。19.6节和19.7节讨论了URLReuest 的基本用法。

下面让我们来看一个完整的例子,首先创建客户端ActionScript代码,然后选择一种服务端解决方案,如服务端脚本Perl, PHP, 或ColdFusion。
+展开
-ActionScript
package {
import flash.display.*;
import flash.text.*;
import flash.filters.*;
import flash.events.*;
import flash.net.*;
public class XMLSendLoadExample extends Sprite {
private var _message:TextField;
private var _username:TextField;
private var _save:SimpleButton;
public function XMLSendLoadExample( ) {
initializeDispaly( );
}
private function initializeDispaly( ):void {
_message = new TextField( );
_message.autoSize = TextFieldAutoSize.LEFT;
_message.x = 10;
_message.y = 10;
_message.text = "Enter a user name";
_username = new TextField( );
_username.width = 100;
_username.height = 18;
_username.x = 10;
_username.y = 30;
_username.type = TextFieldType.INPUT;
_username.border = true;
_username.background = true;
_save = new SimpleButton( );
_save.upState = createSaveButtonState( 0xFFCC33 );
_save.overState = createSaveButtonState( 0xFFFFFF );
_save.downState = createSaveButtonState( 0xCCCCCC );
_save.hitTestState = save.upState;
_save.x = 10;
_save.y = 50;
// When the save button is clicked, call the handleSave method
_save.addEventListener( MouseEvent.CLICK, handleSave );
addChild( _message );
addChild( _username );
addChild( _save );
}
// Creates a button state with a specific background color
private function createSaveButtonState( color:uint ):Sprite {
var state:Sprite = new Sprite( );
var label:TextField = new TextField( );
label.text = "Save";
label.x = 2;
label.height = 18;
label.width = 30;
var background:Shape = new Shape( );
background.graphics.beginFill( color );
background.graphics.lineStyle( 1, 0x000000 );
background.graphics.drawRoundRect( 0, 0, 32, 18, 9 );
background.filters = [ new DropShadowFilter( 1 ) ];
state.addChild( background );
state.addChild( label );
return state;
}
private function handleSave( event:MouseEvent ):void {
// Generate a random score to save with the username
var score:int = Math.floor( Math.random( ) * 10 );
// Create a new XML instance containing the data to be saved
var dataToSave:XML = <gamescore>
<username>{username.text}</username>
<score>{score}</score>
</gamescore>;
// Point the request to the script that will handle the XML
var request:URLRequest = new URLRequest( "/gamescores.cfm" );
// Set the data property to the dataToSave XML instance to send the XML
// data to the server
request.data = dataToSave;
// Set the contentType to signal XML data being sent
request.contentType = "text/xml";
// Use the post method to send the data
request.method = URLRequestMethod.POST;
// Create a URLLoader to handle sending and loading of the XML data
var loader:URLLoader = new URLLoader( );
// When the server response is finished downloading, invoke handleResponse
loader.addEventListener( Event.COMPLETE, handleResponse );
// Finally, send off the XML data to the URL
loader.load( request );
}
private function handleResponse( event:Event ):void {
try {
// Attempt to convert the server's response into XML
var success:XML = new XML( event.target.data );
// Inspect the value of the success element node
if ( success.toString( ) == "1" ) {
_message.text = "Saved successfully.";
else {
_message.text = "Error encountered while saving.";
}
catch ( e:TypeError ) {
// Display an error message since the server response was not understood
_message.text = "Could not parse XML response from server.";
}
}
}
}

URLRequest 对象的contentType 属性默认设置为application/x-www-form-urlencoded ,当发送XML 数据时必须设置为text/xml ,而且设置method 属性为URLRequestMethod.POST ,表示通过HTTP POST.发送数据。

下一步就是创建服务端脚本,首先看一下Perl脚本,将下列代码保存为gamescores.cgi (或gamescores.pl):
#!/usr/bin/perl
# Flash/Perl+CGI XML interaction demo
# Arun Bhalla (arun@groogroo.com)
use strict;
use XML::Simple;
use CGI;
my $ScoreFile = "scores.txt";
# Here we assume that this CGI script is receiving XML in text/xml
# form via POST. Because of this, the XML appears to the script
# via STDIN.
my $input = XMLin(join('',<STDIN>));
# Write out the HTTP header
print CGI::header('text/xml');
# Try to open score file for writing, or return an error message.
open(SCORES, ">> $ScoreFile") || (printMessage(0) &&
die "Error opening $ScoreFile");
# Save the score in a pipe-delimited text file.
print SCORES join('|', $input->{username}, $input->{score}), "\n";
# Return the result in XML.
printMessage(1);
# Subroutine to output the result in XML.
sub printMessage {
my $value = shift;
my $message = {};
$message->{success} = $value;
print XMLout($message, keeproot => 1, rootname => 'success');
}

如果使用ColdFusion,看下面的例子代码,将它保存为gamescores.cfm :
+展开
-XML
<cfsilent>
<cfsetting enablecfoutputonly="Yes">
<cfset success = 0>
<cftry>
<!--- XML packet sent by Flash. --->
<cfset scores_xml = XmlParse( getHTTPRequestData( ).content ) >
<!--- Parse out the XML packet sent from Flash. --->
<!--- Grab the username and score from the XML document and save as
local variables so they are easier to work with. // -
-->

<cfset username = scores_xml.gamescore.username.XmlText >
<cfset score = scores_xml.gamescore.score.XmlText >
<!--- Append the latest score to our scores file. This could also be
stored in the database or another XML document. // -
-->

<cffile action="APPENDfile="#ExpandPath( 'scores.txt' )#"
output="#username#|#score#|#getHTTPRequestData( ).content#addnewline="Yes">

<cfset success = 1 >
<cfcatch type="Any">
<cfset success = 0 >
<cffile action="APPENDfile="#ExpandPath( 'attempts.txt' )#output="ERROR"
addnewline="Yes">

</cfcatch>
</cftry>
</cfsilent>
<cfcontent type="text/xml">
<cfoutput><?xml version="1.0" ?><success>#success#</success></cfoutput>
<cfsetting showdebugoutput="noenablecfoutputonly="No">

下面是PHP脚本,将它保存为gamescores.php:
+展开
-HTML
<?php
// Read In XML from Raw Post Data.
$xml = $GLOBALS['HTTP_RAW_POST_DATA'];
// Process XML using DOM PHP extension.
$document = xmldoc($xml);
// Read root element <gameinfo>.
$rootElement = $document->root( );
// Read child nodes <username> and <score>.
$childNodes = $rootElement->children( );
$data = "";
// Loop through child nodes and place in array.
foreach($childNodes as $childNode){
// Add data to array;
$name = $childNode->tagName( );
$value = $childNode->get_content( );
$data[$name] = $value;
}
// Append data to scores.txt ( format: username|score )
$fp = fopen("scores.txt","a+");
$dataString = $data['username'] . "|" . $data['score'] . "\n";
fputs($fp,$dataString,strlen($dataString));
fclose($fp);
// Return success code to Flash
echo "<success>1</success>";
?>

加支付宝好友偷能量挖...


评论(0)网络
阅读(79)喜欢(0)flash/flex/fcs/AIR