7

I am trying to figure out how to send a file and paramaters within the same XMLHttpRequest. Is this possible?

Obviously I can do xhr.send(file+params) or xhr.(file,params). And I don't think I can set two different request headers to do this...

xhr.setRequestHead('X_FILENAME', file.name)
xhr.send(file);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(params);

Is there some way to send the params without having to use GET, or a secondary xhr request?

CJT3
  • 2,788
  • 7
  • 30
  • 45
  • 2
    you may have to use FormData https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/FormData – Arun P Johny Mar 05 '13 at 07:44
  • Also refer http://stackoverflow.com/questions/5602021/submitting-a-html-form-with-ajax-that-includes-a-file-input and http://stackoverflow.com/questions/6974684/how-to-send-formdata-objects-with-ajax-requests-in-jquery – Arun P Johny Mar 05 '13 at 07:45
  • @ Charles: How are you sending a file via XHR? Did you read it client-side via the File API, or...? (It matters, because if you read it client-side via the File API, then it's just another parameter...) – T.J. Crowder Mar 05 '13 at 07:49

2 Answers2

12

If you rely on browser which supports FormData, you can use the code below (JavaScript):

var formData = new FormData();
formData.append('param1', 'myParam');
formData.append('param2', 12345); 
formData.append('uploadDir', 'public-data');  
formData.append('myfile', file);

xhr.send(formData);

Then, on your server side you can have access to your variables by using this code (PHP):

<?
  $param1 = $_POST['param1']; //myParam
  $param2 = $_POST['param2']; //12345
  $uploaddir = $_POST['uploadDir']; //public-data
  $fileName = $_FILES['myfile']['name'];
  $fileZise = $_FILES['myfile']['size'];
  $uploaddir = getcwd().DIRECTORY_SEPARATOR.$uploaddir.DIRECTORY_SEPARATOR;
  $uploadfile = $uploaddir.basename($fileName);       
  move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile);
  echo $fileName.' ['.$fileZise.'] was uploaded successfully!';
?>

To get all parameters of $_FILES['myfile'], use var_dump($_FILES["myfile"])

Nolesh
  • 6,848
  • 12
  • 75
  • 112
6

Is there some way to send the params without having to use GET, or a secondary xhr request?

Yes, you can encode them into the URL (just like GET), even though you're doing a POST. E.g.:

xhr.open(yourUrl + "?foo=" + encodeURIComponent(foo) + "&bar=" + encodeURIComponent(bar));
// ...
xhr.send(file);

I'm assuming in the above that you must know something about sending a file via XHR that I don't know. :-)


Assuming that file is the actual content of the file, read via the File API, then isn't it just another parameter? So:

xhr.send(
    "filedata=" + encodeURIComponent(file) +
    "&foo=" + encodeURIComponent(foo) +
    "&bar=" + encodeURIComponent(bar)
);
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • that's kinda what I meant by using GET... I didn't want to append them to the URL. – CJT3 Mar 05 '13 at 07:48
  • @CharlesJohnThompsonIII: Well, it's **not** using `GET`. You're still using `POST`, you're just passing data in two places, which is perfectly normal. If you don't want to send data in the URL, say that, not that you don't want to use `GET`. Those are different statements. – T.J. Crowder Mar 05 '13 at 07:49
  • hmm... would I still access the variables via $_POST server-side? If that's the case then it may be valid. I try and avoid $_GET as it's easier to manipulate the information. – CJT3 Mar 05 '13 at 07:51
  • @CharlesJohnThompsonIII: I'm not a big PHP-head, but I suspect you probably still access them via `$_GET`. But both [`$_POST`](http://php.net/manual/en/reserved.variables.post.php) and [`$_GET`](http://php.net/manual/en/reserved.variables.get.php) are associative arrays of the parameters received (in the relevant part of the request), what makes the associative array in `$_POST` easier to use than the one in `$_GET`? – T.J. Crowder Mar 05 '13 at 07:53
  • I didn't say it was easier to use, it's just not as easy for the user to manipulate the variables – CJT3 Mar 05 '13 at 07:57
  • @CharlesJohnThompsonIII: Ah, I understand that sentence now. Quite true, although of course, you can't trust *anything* the client sends you. :-) – T.J. Crowder Mar 05 '13 at 08:03
  • Its always secure and better to submit forms using $POST. – Codex Jul 27 '18 at 10:08
  • @Codex - POST isn't remotely more secure than GET. But if the call is supposed to change state, POST is the more appropriate choice, since GET is supposed to be idempotent. – T.J. Crowder Jul 28 '18 at 17:31