Ajax file upload with XHRRequest and iframe fallback

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Ajax file upload with XHRRequest and iframe fallback

Bart Veenstra
Hi all,

I managed to get a Ajax file uploade using XMLHttpRequests and iFrame callback working in seaside using the http://valums.com/ajax-upload/ library.

As of now, I managed to get it working on Firefox 3.6, but IE and Chrome are still a bit wierd (the file gets uploaded, but the successfull json response is not handled correctly.

Screenshot before uploading: http://ScrnSht.com/ywmtod 
Screenshot after uploading 2 files: http://ScrnSht.com/lexnyu.

API example:
renderDemoOn: html
         (html div)
script: ((html jQuery this fileUploader)
callback: [:aFile | self files add: aFile. JQWidgetBox.JQFileUploaderResponse success];
allowedExtensions: #(#jpg #jpeg #png #gif);
sizeLimit: 102400000;
onSubmit: (html jQuery ajax script: [:s | s << (s jQuery id: #status) append: [:h | h text: 'Submitting imaged'. h break]]);
onComplete: (html jQuery ajax script: [:s |
s << (s jQuery id: #status) append: [:h | h text: 'Image saved'. h break].
s << (s jQuery id: #images) html: [:h | self files do: [:file | self renderFile: file on: h]]]);
parameters: Seaside.GRSmallDictionary new);
with: 
[html
html: '<noscript><p>Oops, I need javascript to work.</p></noscript>'].
html div id: #status.
html div id: #images

renderFile: file on: html
html paragraph: [ html image width: 100; height: 100; document: file rawContents mimeType: file contentType greaseString]

To get this working I had to change the requestFieldsFor: aNativeRequest method in the SeasideMarshaler for it to handle the XHR upload correctly. This breaks the rest of my applications, when using JQuery ajax post callbacks.

requestFieldsFor: aNativeRequest

| fields |
fields := Seaside.WARequestFields new.
(aNativeRequest isMultipart or: [aNativeRequest isBinary])
ifTrue: [ self postEncodedDataFrom: aNativeRequest keysAndValuesDo: [:key :value | fields at: key add: value ] ]
ifFalse: [ self urlEncodedDataFrom: aNativeRequest contents keysAndValuesDo: [:key :value | fields at: key add: value ] ].
^fields

I feel like a bull in a china shop when making these changes, but worked for me for Firefox. Chrome and IE use multipart uploads (WHY CAN'T ALL BROWSERS HANDLE THIS STUFF THE SAME!!). 

Issues:
Upload response not handled correctly in Chrome and IE.

Would anybody be interested helping me with getting this to work on all modern browsers?

I plan to put this in the JQuery Widgetbox package on Pharo (as well as my other JQWidgetBOx plugins like JQGrid with editing functionality, JSTree and JQAddress for history support in ajax applications (screenshot at:http://ScrnSht.com/afrqgq. This is a dutch dating website I am creating in seaside :D. Don't mind the content, look at the goodies :) ) )

Also, I would like to learn more on how to share my VW JQuery plugins to Pharo. I anyone willing to help me with porting those? I can setup a public VW repository holding those plugins or put it in the cincom public repos).

The JQFileUploaded is available in the Cincom Public Repository:

Packages required: 

JQWidgetBox-Namespace
JQWidgetBox-FileUploader-Core
JQWidgetBox-FileUploader-Dev

Feel free to contact me anytime.

Kind regards,

Bart Veenstra





_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Ajax file upload with XHRRequest and iframe fallback

Philippe Marschall
2010/9/4 Bart Veenstra <[hidden email]>:

> Hi all,
> I managed to get a Ajax file uploade using XMLHttpRequests and iFrame
> callback working in seaside using the http://valums.com/ajax-upload/
> library.
> As of now, I managed to get it working on Firefox 3.6, but IE and Chrome are
> still a bit wierd (the file gets uploaded, but the successfull json response
> is not handled correctly.
> Screenshot before uploading: http://ScrnSht.com/ywmtod
> Screenshot after uploading 2 files: http://ScrnSht.com/lexnyu.
> API example:
> renderDemoOn: html
>          (html div)
> script: ((html jQuery this fileUploader)
> callback: [:aFile | self files add:
> aFile. JQWidgetBox.JQFileUploaderResponse success];
> allowedExtensions: #(#jpg #jpeg #png #gif);
> sizeLimit: 102400000;
> onSubmit: (html jQuery ajax script: [:s | s << (s jQuery id: #status)
> append: [:h | h text: 'Submitting imaged'. h break]]);
> onComplete: (html jQuery ajax script: [:s |
> s << (s jQuery id: #status) append: [:h | h text: 'Image saved'. h break].
> s << (s jQuery id: #images) html: [:h | self files do: [:file | self
> renderFile: file on: h]]]);
> parameters: Seaside.GRSmallDictionary new);
> with:
> [html
> html: '<noscript><p>Oops, I need javascript to work.</p></noscript>'].
> html div id: #status.
> html div id: #images
> renderFile: file on: html
> html paragraph: [ html image width: 100; height: 100; document: file
> rawContents mimeType: file contentType greaseString]
> To get this working I had to change the requestFieldsFor: aNativeRequest
> method in the SeasideMarshaler for it to handle the XHR upload correctly.
> This breaks the rest of my applications, when using JQuery ajax post
> callbacks.
> requestFieldsFor: aNativeRequest
> | fields |
> fields := Seaside.WARequestFields new.
> (aNativeRequest isMultipart or: [aNativeRequest isBinary])
> ifTrue: [ self postEncodedDataFrom: aNativeRequest keysAndValuesDo: [:key
> :value | fields at: key add: value ] ]
> ifFalse: [ self urlEncodedDataFrom: aNativeRequest contents keysAndValuesDo:
> [:key :value | fields at: key add: value ] ].
> ^fields
> I feel like a bull in a china shop when making these changes, but worked for
> me for Firefox. Chrome and IE use multipart uploads (WHY CAN'T ALL BROWSERS
> HANDLE THIS STUFF THE SAME!!).
> Issues:
> Upload response not handled correctly in Chrome and IE.
> Would anybody be interested helping me with getting this to work on all
> modern browsers?

What I usually do when I encounter such problems:

 1. Curse
 2. Fire up tcpdump (tcpdump -i lo -vvv -n -s 0 -w ~/upload-1.dump) to
capture what the browser sent. Yes, you have to do this for every
browser.
 3. Use wireshark to inspect at what actually went over the wire
 4. Only now fire up the Smalltak debugger. Step through the server,
adapter and Seaside to find out where the problem happens.

Socket streams are quite hard to inspect that's why I do the
tcpdump/wireshark tango first so that I know what will come over the
socket.

Hope that helps.

Cheers
Philippe

> I plan to put this in the JQuery Widgetbox package on Pharo (as well as my
> other JQWidgetBOx plugins like JQGrid with editing functionality, JSTree and
> JQAddress for history support in ajax applications (screenshot
> at:http://ScrnSht.com/afrqgq. This is a dutch dating website I am creating
> in seaside :D. Don't mind the content, look at the goodies :) ) )
> Also, I would like to learn more on how to share my VW JQuery plugins to
> Pharo. I anyone willing to help me with porting those? I can setup a public
> VW repository holding those plugins or put it in the cincom public repos).
> The JQFileUploaded is available in the Cincom Public Repository:
> Packages required:
> JQWidgetBox-Namespace
> JQWidgetBox-FileUploader-Core
> JQWidgetBox-FileUploader-Dev
> Feel free to contact me anytime.
> Kind regards,
> Bart Veenstra
>
>
>
>
> _______________________________________________
> seaside mailing list
> [hidden email]
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
>
>
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside