Detailed simple explanation about the examples in developer.mozilla.org docs, its a bit hard to get examples

have you read this https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Submitting_forms_and_uploading_files?

or the more basic one https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects?

a bit hard and un-copy-pasteable. after that you may read my own a bit more generic exmamle.

so lets start with the 2nd link, which is supposely simple, but there are a couple of catches.

1st, although it says, you can only create a FormData with a form element, which is a bit problematic in many cases where you can only have 1 form like in asp.net or sharepoint.

the solution will be presented down here with the explanation about the upper link, and in a more generic example in my other post here

2nd is in the jquery example, where they say you can turn off the proccessData and contentType, which although true, but that means you need to break the request hardcoded, and that in managed frameworks you'll get the raw stream of the request instead of the Request Obj with form array and files array.

the solution is presented in the upper link which at this point i would like you to read it.

now lets start the overview and try to make it simple

DISCALIMER:

DISCALIMER - the articles are really good and technical, but as a simple programmer i would also like a parralel more simple explanation to catch it more easly.
DISCALIMER - lets remember that if you're not using ajax to post files you don't really need all this.
DISCALIMER - all this is relevant to HTML5 only, meaning IE10+ (and chrome ect., other browsers support is here).

the very 1st thing they show you is how to use ajax with native js, we all used to the jquery way, which is a wrapper to that, so just translate var oReq = new XMLHttpRequest(); $.ajax({... and oReq.onload = reqListener; is the success function, while the data parameter is this.responseText .

so just understand these differences along the way.

Types of requests

all that paragrath can be translated to "in oReq.open("get", "yourFile.txt", true)the 3rd param is sync or async, but sync is being deprecated so nevermind".

Handling responses

its a technical overview about the response types and its proccessing, basically it talks about you being able to tell ajax that you're asking for JSON so that you get a Json Object, or text for text, html, xml, ect., nowadays we mostly use either JSON or HTML, and files, which brings us to

Handling binary data

this is just basic examples how to RETRIEVE binary data from server, such as a file.

Monitoring progress

with jquery ajax its success, error, complete, done, ect., they are all callback to be called according to what happens (i.e. events), so here they show how to use them natively.

*you can start to get sence here why people are talking about stop using JQuery, since most stuff are being enabled easy with native code or CSS3, which is also the reason for changes in the JQ releases.

Submitting forms and uploading files

this is where we really want to get.
so as said before, if you're here either you really enjoy my writting, or you want to take a custom form you made in a div, not the entire form, containing a file input, and send is via ajax.
you are also not satisfied about adding the fields one by one spec. earlier. so lets talk about it.

there are two examples 
  • using nothing but AJAX
  • using the FormData API
i'll jump to "using nothing but ajax", since "using the FormData API" is just a bit more complex example of the simple use of FormData while just a small part of pure ajax. so

Using nothing but XMLHttpRequest

A brief introduction to the submit methods

this is just an overview about the other standard method, in case you want to use GET or JSON ect., i won't stall for that since in these cases you'll work faster with simpe Jquery Ajax examples, except this:

Method: POST; Encoding type: multipart/form-data:
this is the method we will use, since we can put a binary string as value, like a files.

the contentType, where you are used to write "json" changed to

"Content-Type: multipart/form-data; boundary=---------------------------314911788813839"

multipart/form-data means that it uses the FormData API/tech.

the boundary is what tells the seperation between key-value pairs. it can anything as explained is this stack answer, in the example the use a large obvious one which is all the dashes and numbers.

-----------------------------314911788813839
Content-Disposition: form-data; name="foo"

bar
this is the data property you are used with the $.ajax, where is json you send a json obj, here you will send a lot of text containing for each key-value a line with the boundary, another line with Content-Disposition.... with the name of the prop in the end, a blank line, the value, and another 2 blank lines, and again and again for each prop.

this is the basic.

now they made a small js class to handle it so lets explain it a bit.
the code is build to use all content types and methods explained above, so i'll give a quick overview about them too.

A little vanilla framework

XMLHttpRequest.prototype.sendAsBinary = function(sData) {
not all browsers support this feature, so its a "just in case" polyfill, read more here

var AJAXSubmit = (function () {
for any1 that dont know yet, if you want to create an object that hides all his inner props, you do it like this

var x = function(){
....
return { y : innerFunction, z : innerMember }
};

now x only have y and z to be used.

and for auto CTOR its function () {...}();
and finally the () that wraps the function is to encapsulate it.


for the rest of the object i'll start from the bottom.

return function (oFormElement) {
    if (!oFormElement.action) { return; }
since we encapsulated and auto-CTOR it, we can now use AJAXSubmit as a function that accept a single param, as stated in the return of its own CTOR func.
the func there expect a form element and tests is by checking if it has an action attribute.

new SubmitRequest(oFormElement);
the CTOR now again return a different object, sending us to the SubmitRequest func.
in the 1st line some variables are stated, notice the bIsPost that already gets value sets.

this.technique
this is the framework defining what data method we will send the form, could have been JSON, but here its either GET with everything in the url, simple text structure in the body, or multipart text structure, i.e. formdata, look later @ the submitData func

this.segments = [];
thats actually the array of our inputs, since either way its gonna be a string structure, it just pushed the input key/val in the relevant format.

this.status = 0;
since eventually, reading a file is done async, we need something to tell us that the body is not done yet, so they increment it for each file, and decrements per file done as seen in pushSegment func.

from here its now a bit more readable.

processStatus(this);
in the end, the data object is "this", as seen that all the relevant variables were defined as "this.varName", while the non-relevant for the next func. were defined as var bla, bla2, bla3...

so lets go to processStatus

if (oData.status > 0) { return; }
that a nice smart recursion, if the status isnt 0 so we have a file being read, so bye bye.

but wait!! the code flow is now over!!
nope,
function pushSegment (oFREvt) {
pushSegment is a callback, and is called whenever a file is finished reading, and is calling processStatus again :D

submitData (oData);
so ye, in processStatus you can do final manipulation, dont know what could it be....

var oAjaxReq = new XMLHttpRequest();
so back to standard ajax request, that is now so simple you dont need jquery anymore.
if (oData.technique === 0) {
      /* method is GET */
put everything in URL

} else {
      /* method is POST */
put everything in the post body

if (oData.technique === 3) {
        /* enctype is multipart/form-data */
build the request as multipart (formData) format

hope i made ur life easier :D

Comments

Popular posts from this blog

OverTheWire[.com] Natas Walkthrough - JUST HINT, NO SPOILERS

SOLVED The item could not be indexed successfully because the item failed in the indexing subsystem

Asp.Net Ending Response options, Response.End() vs CompleteRequest()