我有一个flex应用程序想要在同一个POST请求中将两个图像上传到rails服务器。我想我正在创建POST请求的数据部分,但我不确定。当我打印导轨侧面的参数时,我只看到一个文件。
public class MultipartDataHandler extends EventDispatcher
{
//<net:URLLoader id="loader" complete="completeHandler(event)" dataFormat="binary" />
private var loaderContext:LoaderContext = new LoaderContext(true);
private var loader:URLLoader = new URLLoader();
public function MultipartDataHandler()
{
}
public function sendToServer(exteriorBitmapData:BitmapData, interiorBitmapData:BitmapData):void {
var xml_file:String = UserPreference.getInstance().toXML().toXMLString();
var gongos_id:int = UserPreference.getInstance().gongosId;
var room_id:int = UserPreference.getInstance().roomId;
var car_id:int = UserPreference.getInstance().theCar.id;
// 1. Encode image as a png
// var bitmap:Bitmap = image.content as Bitmap;
// var bytes:ByteArray = pngEncoder.encode(bitmap.bitmapData);
var pngEncoder:PNGEncoder = new PNGEncoder();
var exteriorBytes:ByteArray = pngEncoder.encode(exteriorBitmapData);
var interiorBytes:ByteArray = pngEncoder.encode(interiorBitmapData);
// 2. Create multip part request
var boundary:String = '------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7';
var url:String = UserPreference.urlize("/cars/upload.xml");
var request: URLRequest = new URLRequest(url);
request.data = getMultiPartRequestData(boundary, 'car', exteriorBytes, interiorBytes, xml_file, gongos_id, room_id, car_id);
request.method = URLRequestMethod.POST;
request.contentType = "multipart/form-data; boundary=" + boundary;
// 3. Send to Server
loader.load(request);
loader.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
loader.addEventListener(Event.COMPLETE, loaderCompleteHandler);
}
private function getMultiPartRequestData(boundary:String, resourceName:String,
exteriorBytes:ByteArray,
interiorBytes:ByteArray,
xml_file:String,
gongos_id:int, room_id:int, car_id:int):ByteArray {
var lf:String = "\r\n";
var part1:String = '--' + boundary + lf +
'Content-Disposition: form-data; name="Filename"' + lf + lf +
'{0}' + lf +
'--' + boundary + lf +
'Content-Disposition: form-data; name="{1}[xml]"' + lf + lf +
'{2}' + lf +
'--' + boundary + lf +
'Content-Disposition: form-data; name="gongos_id"' + lf + lf +
'{3}' + lf +
'--' + boundary + lf +
'Content-Disposition: form-data; name="room_id"' + lf + lf +
'{4}' + lf +
'--' + boundary + lf +
'Content-Disposition: form-data; name="car_id"' + lf + lf +
'{5}' + lf +
'--' + boundary + lf +
'Content-Disposition: form-data; name="{1}[photo]"; ' +
'filename="{0}"' + lf +
'Content-Type: application/octet-stream' + lf +lf;
var part2:String = '--' + boundary + lf +
'Content-Disposition: form-data; name="{1}[interior_photo]"; ' +
'filename="{0}"' + lf +
'Content-Type: application/octet-stream' + lf +lf;
var part3:String = '--' + boundary + lf +
'Content-Disposition: form-data; name="Upload"' + lf + lf +
'Submit Query' + lf +
'--' + boundary + '--';
part1 = StringUtil.substitute(part1, 'car.png', resourceName,
xml_file, gongos_id, room_id, car_id);
part2 = StringUtil.substitute(part2, 'interior.png', resourceName);
var result:ByteArray = new ByteArray();
result.writeMultiByte(part1, "ascii");
result.writeBytes(exteriorBytes, 0, exteriorBytes.length)
result.writeMultiByte(part2, "ascii");
result.writeBytes(interiorBytes, 0, interiorBytes.length)
result.writeMultiByte(part3, "ascii");
trace(part1 + "EXTERIOR BYTES" + part2 + "INTERIOR BYTES" + part3);
return result;
}
}
}
这是调试控制台打印的内容。请注意,我不会在控制台中打印实际字节,因为这会非常痛苦,但您可以看到它们的去向。
--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="Filename"
car.png
--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="car[xml]"
<creation>
<car>
<bodyId>1</bodyId>
<themeId>0</themeId>
<roomId>0</roomId>
<userId>0</userId>
<name>null</name>
<exterior/>
<interior/>
</car>
</creation>
--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="gongos_id"
0
--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="room_id"
1
--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="car_id"
0
--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="car[photo]"; filename="car.png"
Content-Type: application/octet-stream
EXTERIOR BYTES--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="car[interior_photo]"; filename="interior.png"
Content-Type: application/octet-stream
INTERIOR BYTES--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="Upload"
Submit Query
--------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7--
最后,这就是Rails所说的。
--- !map:HashWithIndifferentAccess
room_id: "1"
Filename: car.png
format: xml
action: upload
car_id: "0"
controller: cars
car: !map:HashWithIndifferentAccess
photo: !ruby/object:File {}
xml: |-
<creation>
<car>
<bodyId>1</bodyId>
<themeId>0</themeId>
<roomId>0</roomId>
<userId>0</userId>
<name>null</name>
<exterior/>
<interior/>
</car>
</creation>
gongos_id: "0"
Processing CarsController#upload to xml (for 127.0.0.1 at 2011-03-17 08:05:00) [POST]
Parameters: {"Filename"=>"car.png", "room_id"=>"1", "car_id"=>"0", "car"=>{"photo"=>#<File:/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/RackMultipart20110317-24400-14hcvab-0>, "xml"=>"<creation>\n <car>\n <bodyId>1</bodyId>\n <themeId>0</themeId>\n <roomId>0</roomId>\n <userId>0</userId>\n <name>null</name>\n <exterior/>\n <interior/>\n </car>\n</creation>"}, "gongos_id"=>"0"}
[paperclip] identify '-format' '%wx%h' '/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/stream,24400,0.png[0]' 2>/dev/null
[paperclip] convert '/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/stream,24400,0.png[0]' '-resize' '500x500>' '/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/stream,24400,0,24400,0' 2>/dev/null
[paperclip] identify '-format' '%wx%h' '/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/stream,24400,0.png[0]' 2>/dev/null
[paperclip] convert '/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/stream,24400,0.png[0]' '-resize' '250x250>' '/var/folders/f6/f6zP-E52HiaycvHwz90OtE+++TI/-Tmp-/stream,24400,0,24400,1' 2>/dev/null
User Load (0.3ms) SELECT * FROM "users" WHERE ("users"."gongos_id" = '0' AND "users"."room_id" = '1') LIMIT 1
Car Create (81.1ms) INSERT INTO "cars" ("name", "interior_photo_file_name", "room_id", "photo_file_size", "interior_photo_file_size", "interior_photo_updated_at", "created_at", "xml", "photo_file_name", "updated_at", "body_id", "photo_content_type", "deleted", "user_id", "interior_view_id", "theme_id", "photo_updated_at", "parent_car_id", "interior_photo_content_type") VALUES('Faxo', NULL, NULL, 102547, NULL, NULL, '2011-03-17 12:05:03', '<creation>
<car>
<bodyId>1</bodyId>
<themeId>0</themeId>
<roomId>0</roomId>
<userId>0</userId>
<name>null</name>
<exterior/>
<interior/>
</car>
</creation>', 'car.png', '2011-03-17 12:05:03', 1, 'application/octet-stream', NULL, NULL, NULL, 0, '2011-03-17 12:05:01', NULL, NULL)
[paperclip] Saving attachments.
[paperclip] saving /Users/glurban/code/amfdreamcar/public/system/photos/18/medium/car.png
[paperclip] saving /Users/glurban/code/amfdreamcar/public/system/photos/18/original/car.png
[paperclip] saving /Users/glurban/code/amfdreamcar/public/system/photos/18/thumb/car.png
[paperclip] Saving attachments.
Rendering cars/upload
Completed in 2750ms (View: 60, DB: 81) | 200 OK [http://localhost/cars/upload.xml]
所以,正如你所看到的,只有一张照片(第一张)似乎出现在参数中。切换订单只会显示interior_photo
。我做错了什么?
我还尝试将两个单独的调用链接在一起,但由于Flash 10的安全限制而导致文件上传失败,而用户无需执行操作(例如单击按钮)。我甚至尝试将loader.load()
的两个调用放在同一个函数中,使用随机数生成器在flex端创建一个id(因为rails需要知道这两个调用是针对同一辆汽车的,并且没有链接我不能使用第一次调用的响应来传回汽车ID),但我遇到了竞争条件,第二次调用以某种方式在第一次调用之前到达服务器。 Adobe安全... FFFFFFFUUUUUU。
答案 0 :(得分:0)
天啊。
花了3个小时解决这个问题(调试,尝试其他失败的解决方案等)。
然后,在我发布之后,我意识到了这个问题:
换行将是我的死亡。将lf
添加到part2和part3的前面,我们很好。
:o