Closed Bug 528524 Opened 15 years ago Closed 14 years ago

add a scriptable API for generating multipart/form-data request bodies usable with XMLHttpRequest

Categories

(Core :: DOM: Core & HTML, defect)

defect
Not set
normal

Tracking

()

VERIFIED DUPLICATE of bug 546528

People

(Reporter: ted, Unassigned)

References

()

Details

(Keywords: student-project)

Currently AFAIK there is no way to send a multipart/form-data request via XMLHttpRequest without manually generating the request body. This sucks because we have code to do that, but you can't use it without creating an actual <form> and submitting it. For example, I wound up using an <iframe> with a <form> to submit crash reports from about:crashes, which is kind of awful. I think we should add a scriptable API that would build the request body for you given form fields. Here's a (not-very thorough) proposal:

var f = new MozMultipartFormData();
f.addField("foo", "bar");
f.addFile("somefile", file);
var req = new XMLHttpRequest();
req.open('POST', 'myform.php', false);
req.overrideMimeType('multipart/form-data');
req.send(f);

This should send a request equivalent to submitting:
<form method="POST" action="myform.php" enctype="multipart/form-data">
<input type="text" name="foo" value="bar">
<input type="file" name="somefile">
</form>

The "addFile" method could take a DOM node representing <input type=file>, an nsIDOMFile, or an nsILocalFile.

As an additional nicety, XHR could auto-set the Content-Type to multipart/form-data if send is called with a MozMultipartFormData object.
Maybe XHR could also handle form elements.

var xhr = new XMLHttpRequest();
xhr.open("POST", "someform.pl");
xhr.send(document.getElementsByTagName('form')[0]);
I thought about that too, but seemed like overkill to have to create a form if you didn't want one. Although I suppose the primary use case of this would involve sending files, so if you're in content script you have to create an <input type=file> to get a file anyway.
(In reply to comment #0)
> req.open('POST', 'myform.php', false);
And please don't use synchronous XHR ;)
We probably need a few more pieces of info here (e.g. encoding to use and such), but we should totally do this.  jst, anyone free to work on this?
Keywords: student-project
Could we do that perhaps with a .jsm file?  I've written code before to do this for XUL (serverpost).  It wouldn't be that hard to port over.
I think this should be web-accessible. We should use the same code we use for regular form POST, not some second implementation.
We talked about this at TPAC last week, and Anne a few days ago added the capability to the XHR L2 spec:

http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface
Oh, and the intent is that you get a FormData object from a <form> element. So you could do stuff like

xhr.send(myFormElement.formData);

or even

formData = myFormElement.formData;
formData.append("foo", "bar");
xhr.send(formData);

However this part hasn't been specified yet as far as I can see.
That seems a little silly. If you already have a <form> why not just do like smaug suggests and pass the form element directly? If you don't want to use the form element, you should be able to construct a FormData without a <form>.
Otherwise, that interface looks pretty sane, although I don't see file entries mentioned specifically.
(In reply to comment #9)
> That seems a little silly. If you already have a <form> why not just do like
> smaug suggests and pass the form element directly?

So that you can add additional fields to the FormData object for things that aren't in the form.

It also allows us to do things like passing an arbitrary node to the xhr.send() method and have just the serialization (.innerHTML) of that node be sent. I believe some browsers support this already. 

> If you don't want to use the
> form element, you should be able to construct a FormData without a <form>.

You can do that with the API defined in the spec. See link in comment 7 and search for "constructor".

The idea is that you can *either* start from scratch using |x = new FormData()| *or* you can start using the data that's in the a form and optionally add more data to it.
Ah, I must have missed that. That sounds like exactly what I want, then. The append() method does seem to be a little vague on adding file entries, as I mentioned in comment 10. Sounds like we should just implement that part of the spec.
Any amount of detail the specification is missing is probably missing in HTML5 too. I more or less copied the <form> model defined there.
<form>.formData seems like something HTML5 ought to define so I have not done that. XMLHttpRequest.send(HTMLFormElement) is an interesting idea too. I suggest we gain some more experience with plain FormData first before adding more features.
Done and done
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → DUPLICATE
<3
Status: RESOLVED → VERIFIED
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.