This is little strange and I hope someone has some insight.

I have a module that draws a form for user input. The form has a fieldset containing groups of fields. A new group can be added to the fieldset using an "Add More" AHAH click event. I borrowed this from the poll module and it works quite well.

Later on in the form there are 5 File Upload fields. If a user clicks Browse on one of them and selects a file, the path to the file is placed in the Upload field. At that point, something happens that breaks the AHAH in the earlier fields.

When clicking the "Add More" button, the pounder runs, but an alert pops with the message "An HTTP error 0 occurred."

As long as there are no files selected for upload the AHAH runs fine.

I have tested this in Firefox 3.0.7 as well as Safari 4 beta. The behavior is the same.

As far as I can tell, if there are no files selected for upload, when the "Add More" button is clicked, the Request Headers in the AHAH post look like this:

Request Headers
Host

my.devserver.com (altered by poster)

User-Agent

Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.7) Gecko/2009021906 Firefox/3.0.7

Accept

application/json, text/javascript, */*

Accept-Language

en-us,en;q=0.5

Accept-Encoding

gzip,deflate

Accept-Charset

ISO-8859-1,utf-8;q=0.7,*;q=0.7

Keep-Alive

300

Connection

keep-alive

Content-Type

application/x-www-form-urlencoded; charset=UTF-8

X-Requested-With

XMLHttpRequest

Referer

http://my.devserver.com/form (altered by poster)

Content-Length

1455

Cookie

__utma=226879900.1564037193.1215103093.1235157439.1236264856.29; __utmz=229608960.1229635503.1.1.utmcsr
=(direct)|utmccn=(direct)|utmcmd=(none); phpbb3_6we8t_sid=622df62ad9dcdc659841ff8b0531f583; __utma=229608960
.1031987854422264000.1229635503.1229635503.1229635503.1; fboard_settings[current_view]=threaded; style_cookie
=A; fboard_settings[member_id]=91; __utmz=226879900.1221507406.18.3.utmccn=(referral)|utmcsr=pickeringportal
.com|utmcct=/administrator/index2.php|utmcmd=referral; phpbb3_6we8t_u=1; phpbb3_6we8t_k=; SESSa2e96055525026cbf9468a347c91a8c2
=0916gc0toh3dp8ni4ob1dkrer3; has_js=1; com_jw_fpss=true

Pragma

no-cache

Cache-Control

no-cache

But once a file is selected for upload, and the "Add More" button is clicked again, the Request headers look like this:

Request Headers
Host

my.devserver.com (altered by poster)

User-Agent

Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.7) Gecko/2009021906 Firefox/3.0.7

Accept

text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language

en-us,en;q=0.5

Accept-Encoding

gzip,deflate

Accept-Charset

ISO-8859-1,utf-8;q=0.7,*;q=0.7

Keep-Alive

300

Connection

keep-alive

Referer

http://my.devserver.com/form (altered by poster)

Cookie

__utma=226879900.1564037193.1215103093.1235157439.1236264856.29; __utmz=229608960.1229635503.1.1.utmcsr
=(direct)|utmccn=(direct)|utmcmd=(none); phpbb3_6we8t_sid=622df62ad9dcdc659841ff8b0531f583; __utma=229608960
.1031987854422264000.1229635503.1229635503.1229635503.1; fboard_settings[current_view]=threaded; style_cookie
=A; fboard_settings[member_id]=91; __utmz=226879900.1221507406.18.3.utmccn=(referral)|utmcsr=pickeringportal
.com|utmcct=/administrator/index2.php|utmcmd=referral; phpbb3_6we8t_u=1; phpbb3_6we8t_k=; SESSa2e96055525026cbf9468a347c91a8c2
=0916gc0toh3dp8ni4ob1dkrer3; has_js=1; com_jw_fpss=true

The Accept header looks different and there seems to be some headers missing. I'm not an expert on HTTP headers, so reading those is a little difficult.

Does Drupal do any kind of event modifications on the change of a File field?
I'm grasping a little there...

To clarify, I am not using CCK FileFields or anything like that. This is a completely custom module/form build with the Drupal 6 FAPI.

If anyone has any insight into this I would really appreciate it.

Thanks!
-nash

Comments

jleonard’s picture

I encountered exactly the same problem.

If you are like me, and you are basing your code on katbailey's excellent article, Doing AHAH Correctly in Drupal 6 and beyond (http://drupal.org/node/331941), you may have code in your ahah handler that looks something like this:

   $javascript = drupal_add_js ( NULL, NULL, 'header' );
   drupal_json (
       array (
           'status' => TRUE,
           'data' => theme ( 'status_messages' ) . $output,
           'settings' => call_user_func_array (
               'array_merge_recursive', $javascript['setting'] )
       )
   );
 

This does not work. Grasping a straws after many hours, I hijacked a couple lines of code from the upload module (including comments):

  // send the updated file attachments form...  don't call drupal_json().
  // ahah.js uses an iframe and the header output by drupal_json() causes
  // problems in some browsers.
  print drupal_to_js ( array ( 'status' => TRUE, 'data' => $output ) );
  exit;

and voila! Everything works. (note. the exit statement is necessary).

Now, I would love for somebody to explain to me what is going on here. My original code works perfectly for any other type (textfield, for example). Only the file type causes a problem. The html that I am sending to the browser looks good -- it's exactly what the form engine sends in the first place. And moreover, my code is in a skeletal stage where I am doing nothing with the file that gets submitted -- all I want to do is ignore it and paint the screen with a fresh new file input.

If somebody in the community can give me (and jimmynash) a bit of insight into what is going on here, you would be doing us a great service -- something is up at the protocol level, but this is certainly not my area of expertise. Is this a bug?

Thanks in advance, I would really love to understand what is happening here.
Cheers all!

cdale’s picture

What is going on here, is when the form contains a file field that needs uploading, Drupal's ahah.js actually creates a hidden iframe to do the upload. This is why the request headers are different, one is coming from a pure javascript XHR request object, the other, is actually coming from an iframe that is sipmly behaving as if someone clicked a 'submit' button inside it.

Once you understand that, you start to understand why drupal_json(), which simply sets the "text/javascript" content type header, does not work with file uploads.

A good way to understand why this causes a problem is to think of the iframe as a browser instance and the normal XHR request as an object whose purpose is to retrieve the response from the server, but not act on it.

When the iframe gets a response, it attempts to "render" the data based on the headers received. If it can't do this, or does not know how, then it spits out an error. The XHR object on the other hand, does not attempt to render anything, merely passing the data it received onto the script for the script to do something with it.

By using the hidden iframe method, the AHAH callback request is no longer strictly AJAX, as the iframe should really be considered a separate browser instance that tries to render the request it recieves, where as normal AJAX calls using the XHR object know not to try to render the data. They just pass it on.

I hope this helps explain it?

OuranosSkia’s picture

Do you know what the iframe sends to the callback function when it does the call? I have an ahah call that performs an action based on the value of a field when the call is made. This normally works fine, but it breaks when a file is selected in a file field. Drupal doesn't complain or anything, it just doesn't pass the value of the field in for some reason.

Is there any way to keep drupal from using the iframe? I'm not trying to deal with the file at that time, so i don't really see a purpose for drupal handling it that way.

geoffreyr’s picture

I've also been having issues with AHAH Helper and file upload fields in Internet Explorer. Specifically, the presence of file upload fields prompts IE to try and download the AJAX response instead of rendering it in page. I can verify that this change fixes the problem, at least for the time being.

davidshaw’s picture

After days of frustration with my custom ahah form text field not keeping its values unless the form file field had been uploaded first I found that the ahah.js iframe behaviour of filefield and imagefield can conflict with other ahah functions sitting on other form fields. Patching ahah.js by following patch #19 here fixed this for me.
http://drupal.org/node/806500#comment-4004316

Similar behaviour occurs with CCK imagefield CCK filefield and this patch to ahah.js seems to help with all of them.

Mark in SC_USA’s picture

I found this thread searching for the cause of an HTTP Error 0 when adding controls to a form via AHAH.

In my case I couldn't attribute the error to anything specific, although it likely was.

The error kept indicating the AHAH callback in my hook_menu, so I started looking there. The AHAH code itself was modified from an example I found online, so I went back and started to compare the example to my code.

The only thing I could find different was in my code, after running the module through coder, I had added some check_plain() code at suggested locations.

Since I wasn't displaying any of the text as HTML, and I don't give a flip about any IE 6 problems, I removed it, cleared cache, and haven't had a problem since.

In each instance, the check_plain() was added to either a $_POST variable or a $form variable (form_id, etc). I'm not quite clear at this point how check_plain() could cause an HTTP Error 0 (I'm told this error essentially means an AJAX request was cancelled).

If anyone has more info on this I would really like to know.

Later that evening........

The problem surfaced again. I ran the code through a debugger and found it always failed on the line containing drupal_json(). Did some digging and found this post: http://pastebin.com/vSBZzQKf.

Switched from drupal_json() to drupal_to_js() and the problem is gone.

Regards,

Mark