6

I'm trying to send a multipart/form-data content-type request:

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function(){
    if(xhr.readyState==4){
         alert(xhr.responseText);
    }
}

xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type","multipart/form-data; boundary=---------------------------275932272513031");

xhr.send('-----------------------------275932272513031 Content-Disposition: form-data; name="name"

test

----------------------------275932272513031--');

Then in php I just print the $_POST array

print_r($_POST);

But I get an empty array each time. I expect to see

Array (
    name => "test"
)

What am I doing wrong?

php_nub_qq
  • 15,199
  • 21
  • 74
  • 144
  • Why can't you use jQuery? – Glavić Dec 22 '13 at 14:42
  • 1
    @Glavić I'm doing this with an educational purpose – php_nub_qq Dec 22 '13 at 14:43
  • Please post code that reflects your real code. Your current code doesn't even run. Where are your escaped line terminators? – Rob W Dec 22 '13 at 14:52
  • @RobW I'm afraid I don't know what you're talking about. Escaped line terminators? – php_nub_qq Dec 22 '13 at 14:58
  • @RobW I believe they are being automatically converted from the string, as if I inspect the request's `post` section in firebug I see that there are new lines? – php_nub_qq Dec 22 '13 at 15:00
  • 1
    JavaScript doesn't support `"first line[Enter]second line"`. Instead, you have to use `"first line\nsecond line"` if you want to get a string with a line break inside it. – Rob W Dec 22 '13 at 15:03
  • @RobW wow I never expected this. It always seems like the more you think an error is complicated the more it is actually not. You should post that as an answer. Thanks! – php_nub_qq Dec 22 '13 at 15:06
  • 1
    [This link](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest) has nice examples of XMLHttpRequest use, even file upload. – Glavić Dec 22 '13 at 15:13
  • @php_nub_qq — But that would stop the request from submitting at all. You said you got an empty array back. How are you getting anything back? – Quentin Dec 22 '13 at 15:22
  • @Quentin no idea, probably magic – php_nub_qq Dec 22 '13 at 15:25

1 Answers1

7

Your code failed because you've used "Enter" instead of an escaped line break character (\n).
JavaScript doesn't support "first line[Enter]second line". If you need a string with a line break, use "first line\nsecond line".

Once you've fixed this problem, your code should work as intended (with one caveat, see final note):

var xhr = new XMLHttpRequest();
xhr.onload = function() {
     alert(xhr.responseText);
};
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type","multipart/form-data; boundary=---------------------------275932272513031");
xhr.send('-----------------------------275932272513031\n' +
         'Content-Disposition: form-data; name="name"\n\n' +
         'test\n\n' +
         '----------------------------275932272513031--');

NOTE: Your code will only work for payloads that consists of UTF-8 characters, not binary data. If you want to learn more about submitting forms with binary data via XMLHttpRequest, see this answer and its linked references.

Community
  • 1
  • 1
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Awesome, thanks for the reference, really explains a lot now! – php_nub_qq Dec 22 '13 at 15:16
  • 2
    It's maybe helpful to mention that the boundary seperator is always prefixed with two (additional) dashes and suffixed with two more at the end of the body. That is if you have `...boundary=bound750` in the header then in the body you need `--bound750\n` and `--bound750--` as the last line. – TNT Oct 16 '15 at 14:19
  • 1
    ...and that dashes are not required in the boundary at all. It might make sense to change the post to `boundary=275932272513031` and then the two hyphens to each line `--275932272513031` (to clarify the requirement) – Shanimal Jan 08 '16 at 22:06