| NewFolder |
31.10.2008 18:27 |
Посылка файлов на сервер
Эта тема очень часто поднимается на форумах. Почти все советуют способ, при котором на сервер посылается один файл, а на сервере его можно считать только используя $GLOBALS['HTTP_RAW_POST_DATA']. Это довольно таки не удобно. А что если мне нужно отослать несколько файлов сразу?
Немного погуглил и нашёл класс UploadPostHelper. Он отсылает тоже один файл на сервер, но к нему уже можно обращаться через массив $_FILES. Добавил возможность отсылать несколько файлов, предварительно пофиксив в нем глюк. Теперь мы можем отсылать сколько угодно файлов одним запросом и обращаться к ним обычным нам способом.
Пользуйтесь на здоровье!
Сам класс
Код:
package {
import flash.events.*;
import flash.net.*;
import flash.utils.ByteArray;
import flash.utils.Endian;
/**
* Take a fileName, byteArray, and parameters object as input and return ByteArray post data suitable for a UrlRequest as output
*
* @see http://marstonstudio.com/?p=36
* @see http://www.w3.org/TR/html4/interact/forms.html
* @see http://www.jooce.com/blog/?p=143
* @see http://www.jooce.com/blog/wp%2Dcontent/uploads/2007/06/uploadFile.txt
* @see http://blog.je2050.de/2006/05/01/save-bytearray-to-file-with-php/
*
* @author Jonathan Marston
* @version 2007.08.19
*
* This work is licensed under a Creative Commons Attribution NonCommercial ShareAlike 3.0 License.
* @see http://creativecommons.org/licenses/by-nc-sa/3.0/
*
*/
public class UploadPostHelper {
/**
* Boundary used to break up different parts of the http POST body
*/
private static var _boundary:String = "";
private static var files:Array = [];
/**
* Get the boundary for the post.
* Must be passed as part of the contentType of the UrlRequest
*/
public static function getBoundary():String {
if(_boundary.length == 0) {
for (var i:int = 0; i < 0x20; i++ ) {
_boundary += String.fromCharCode( int( 97 + Math.random() * 25 ) );
}
}
return _boundary;
}
/**
* Create post data to send in a UrlRequest
*/
public static function attachFile(fileName:String, byteArray:ByteArray, parameters:Object = null) {
var i: int;
var bytes:String;
var postData:ByteArray = new ByteArray();
postData.endian = Endian.BIG_ENDIAN;
//add Filename to parameters
if(parameters == null) {
parameters = new Object();
}
parameters.Filename = fileName;
//add parameters to postData
for(var name:String in parameters) {
postData = BOUNDARY(postData);
postData = LINEBREAK(postData);
bytes = 'Content-Disposition: form-data; name="' + name + '"';
for ( i = 0; i < bytes.length; i++ ) {
postData.writeByte( bytes.charCodeAt(i) );
}
postData = LINEBREAK(postData);
postData = LINEBREAK(postData);
postData.writeUTFBytes(parameters[name]);
postData = LINEBREAK(postData);
}
//add Filedata to postData
postData = BOUNDARY(postData);
postData = LINEBREAK(postData);
bytes = 'Content-Disposition: form-data; name="' +fileName+ '"; filename="';
for ( i = 0; i < bytes.length; i++ ) {
postData.writeByte( bytes.charCodeAt(i) );
}
postData.writeUTFBytes(fileName);
postData = QUOTATIONMARK(postData);
postData = LINEBREAK(postData);
bytes = 'Content-Type: application/octet-stream';
for ( i = 0; i < bytes.length; i++ ) {
postData.writeByte( bytes.charCodeAt(i) );
}
postData = LINEBREAK(postData);
postData = LINEBREAK(postData);
postData.writeBytes(byteArray, 0, byteArray.length);
postData = LINEBREAK(postData);
//add upload filed to postData
postData = LINEBREAK(postData);
postData = BOUNDARY(postData);
postData = LINEBREAK(postData);
bytes = 'Content-Disposition: form-data; name="Upload"';
for ( i = 0; i < bytes.length; i++ ) {
postData.writeByte( bytes.charCodeAt(i) );
}
postData = LINEBREAK(postData);
postData = LINEBREAK(postData);
bytes = 'Submit Query';
for ( i = 0; i < bytes.length; i++ ) {
postData.writeByte( bytes.charCodeAt(i) );
}
postData = LINEBREAK(postData);
//closing boundary
postData = BOUNDARY(postData);
//postData = DOUBLEDASH(postData);
files.push(postData);
}
public static function getPostData():ByteArray {
var postData:ByteArray = new ByteArray();
postData.endian = Endian.BIG_ENDIAN;
for (var i:int = 0; i < files.length; i++){
postData.writeBytes(files[i], 0, files[i].length);
}
postData = DOUBLEDASH(postData);
return postData;
}
public static function reset():void{
files = [];
}
/**
* Add a boundary to the PostData with leading doubledash
*/
private static function BOUNDARY(p:ByteArray):ByteArray {
var l:int = UploadPostHelper.getBoundary().length;
p = DOUBLEDASH(p);
for (var i:int = 0; i < l; i++ ) {
p.writeByte( _boundary.charCodeAt( i ) );
}
return p;
}
/**
* Add one linebreak
*/
private static function LINEBREAK(p:ByteArray):ByteArray {
p.writeShort(0x0d0a);
return p;
}
/**
* Add quotation mark
*/
private static function QUOTATIONMARK(p:ByteArray):ByteArray {
p.writeByte(0x22);
return p;
}
/**
* Add Double Dash
*/
private static function DOUBLEDASH(p:ByteArray):ByteArray {
p.writeShort(0x2d2d);
return p;
}
}
}
Пример использования
Код:
//Reset uploader object
UploadPostHelper.reset();
//Get url and set post data
var url_request:URLRequest = new URLRequest("script url");
url_request.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary();
url_request.method = URLRequestMethod.POST;
for (var i:int = 0; i < frames.length; i++){
//UploadPostHelper.attachFile(имя файла, ByteArray);
UploadPostHelper.attachFile("file" + i.toString(), frames[i]);
}
url_request.data = UploadPostHelper.getPostData();
trace("Pack size: " + url_request.data.length);
//Send images to the server
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, serverResult);
loader.addEventListener(IOErrorEvent.IO_ERROR, serverResult);
loader.load(url_request);
|