I have read many online articles on this topic. However, they either just show how to do ajax form submission, or how to submit just files. In my case, well I bet in most real life situations, we need to submit both ordinary text/selection/radio values and files.
Here is how to do it.
HTML forms. Yea, whatever. Just set something up.
Submit
Notice I didn’t use the form tag. My philosophy here is that: since we will decide the data set during the ajax submission, there is really no need to declare a form here.
Then here comes the ajax part.
$('document').ready(function(){ // bind actions to the submit button $('#submit_btn').click(function(){ submit_xhr(); }); }); // submission function submit_xhr(){ // our file obj file_obj = document.getElementById('file1').files[0]; // using FormData, makes your life much easier var formData = new FormData(); // append key-value pairs formData.append('text1', $('#text1').val()); formData.append('text2', $('#text2').val()); var xhr = new XMLHttpRequest(); url = "http://somewhere.com/some_dir/upload.php"; type = "POST"; xhr.open(type, url, true); xhr.onload = function(e) { if (xhr.status == 200) { if (xhr.statusText != "OK"){ // something wrong at the server side, not fatal alert(xhr.statusText); return; } // success alert('could do a window.location.replace(url) here'); } else { // error, something bad happened... alert("ErrornStatus: "+xhr.status+"nStatus text: "+xhr.statusText); } }; xhr.send(formData); }
I found FormData very easy and intuitive to use. I recommend using that rather than creating a json array when file sending is involved.
So now, we need to receive the content at the server side.
$text1 = $_POST["text1"]; $text2 = $_POST["text2"]; $file_obj = $_FILES["file1"]; $file_name = $file_obj["name"]; $file_type = $file_obj["type"]; $file_size = $file_obj["size"]; $file_tmp_name = $file_obj["tmp_name"]; $file_error = $file_obj["error"]; // do whatever
The $file_error value should be 0 upon a successful transfer. The $file_tmp_name is a local temp file name containing your file content. Everything feels natural now from this point on. You can also double check the $file_size.
If you are a javascript purist, you may want to try out FileReader. Below is some snippet to get you started.
function read_file_content_and_submit(){ var file_type; var file_name; var reader = new FileReader(); reader.onerror = errorHandler; reader.onload = function(e){ data = { type: file_type, name: file_name, content: reader.result } //alert(data); combine_with_others_then_submit(data); } file_obj = document.getElementById('file1').files[0]; file_type = file_obj.type; file_name = file_obj.name; reader.readAsBinaryString( file_obj ); }
Hope this helps!