Ich habe mir mal den Code von Mozilla geschnappt, und ein bisschen hintendran gehängt. Ich stelle hier zwei Versionen rein, eine (auf en) kommentierte und eine, die (minimal) komprimiert wurde.
Mit Kommentaren:
/*\
|*| AJAX submit for each form of the webpage
|*|
|*| This code can handle all four versions of form submit via AJAX:
|*| GET, POST (text/plain), POST (application/x-www-form-urlencoded) and
|*| POST (multipart/form-data)
|*| How to handle the data within PHP:
|*|
|*| data received via GET
|*| print_r($_GET);
|*|
|*| Data received via POST
|*| print_r($_POST);
|*|
|*| Data received as "raw" (text/plain encoding)
|*| if (isset($HTTP_RAW_POST_DATA)) { echo $HTTP_RAW_POST_DATA; }
|*|
|*| Files received
|*| print_r($_FILES);
\*/
/*\
|*|
|*| :: XMLHttpRequest.prototype.sendAsBinary() Polyfill ::
|*|
|*| https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#sendAsBinary()
\*/
if (!XMLHttpRequest.prototype.sendAsBinary) {
XMLHttpRequest.prototype.sendAsBinary = function(sData) {
var nBytes = sData.length, ui8Data = new Uint8Array(nBytes);
for (var nIdx = 0; nIdx < nBytes; nIdx++) {
ui8Data[nIdx] = sData.charCodeAt(nIdx) & 0xff;
}
/* send as ArrayBufferView...: */
this.send(ui8Data);
/* ...or as ArrayBuffer (legacy)...: this.send(ui8Data.buffer); */
};
}
/*\
|*|
|*| :: AJAX Form Submit Framework ::
|*|
|*| https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest
|*|
|*| This framework is released under the GNU Public License, version 3 or later.
|*| http://www.gnu.org/licenses/gpl-3.0-standalone.html
|*|
|*| Syntax:
|*|
|*| AJAXSubmit(HTMLFormElement);
\*/
var AJAXSubmit = (function () {
function ajaxSuccess () {
/* console.log("AJAXSubmit - Success!"); */
alert(this.responseText);
/* you can get the serialized data through the "submittedData" custom property: */
/* alert(JSON.stringify(this.submittedData)); */
}
function submitData (oData) {
/* the AJAX request... */
var oAjaxReq = new XMLHttpRequest();
oAjaxReq.submittedData = oData;
oAjaxReq.onload = ajaxSuccess;
if (oData.technique === 0) {
/* method is GET */
oAjaxReq.open("get", oData.receiver.replace(/(?:\?.*)?$/, oData.segments.length > 0 ? "?" + oData.segments.join("&") : ""), true);
oAjaxReq.send(null);
} else {
/* method is POST */
oAjaxReq.open("post", oData.receiver, true);
if (oData.technique === 3) {
/* enctype is multipart/form-data */
var sBoundary = "---------------------------" + Date.now().toString(16);
oAjaxReq.setRequestHeader("Content-Type", "multipart\/form-data; boundary=" + sBoundary);
oAjaxReq.sendAsBinary("--" + sBoundary + "\r\n" + oData.segments.join("--" + sBoundary + "\r\n") + "--" + sBoundary + "--\r\n");
} else {
/* enctype is application/x-www-form-urlencoded or text/plain */
oAjaxReq.setRequestHeader("Content-Type", oData.contentType);
oAjaxReq.send(oData.segments.join(oData.technique === 2 ? "\r\n" : "&"));
}
}
}
function processStatus (oData) {
if (oData.status > 0) { return; }
/* the form is now totally serialized! do something before sending it to the server... */
/* doSomething(oData); */
/* console.log("AJAXSubmit - The form is now serialized. Submitting..."); */
submitData (oData);
}
function pushSegment (oFREvt) {
this.owner.segments[this.segmentIdx] += oFREvt.target.result + "\r\n";
this.owner.status--;
processStatus(this.owner);
}
function plainEscape (sText) {
/* how should I treat a text/plain form encoding? what characters are not allowed? this is what I suppose...: */
/* "4\3\7 - Einstein said E=mc2" ----> "4\\3\\7\ -\ Einstein\ said\ E\=mc2" */
return sText.replace(/[\s\=\\]/g, "\\$&");
}
function SubmitRequest (oTarget) {
var nFile, sFieldType, oField, oSegmReq, oFile, bIsPost = oTarget.method.toLowerCase() === "post";
/* console.log("AJAXSubmit - Serializing form..."); */
this.contentType = bIsPost && oTarget.enctype ? oTarget.enctype : "application\/x-www-form-urlencoded";
this.technique = bIsPost ? this.contentType === "multipart\/form-data" ? 3 : this.contentType === "text\/plain" ? 2 : 1 : 0;
this.receiver = oTarget.action;
this.status = 0;
this.segments = [];
var fFilter = this.technique === 2 ? plainEscape : escape;
for (var nItem = 0; nItem < oTarget.elements.length; nItem++) {
oField = oTarget.elements[nItem];
if (!oField.hasAttribute("name")) { continue; }
sFieldType = oField.nodeName.toUpperCase() === "INPUT" ? oField.getAttribute("type").toUpperCase() : "TEXT";
if (sFieldType === "FILE" && oField.files.length > 0) {
if (this.technique === 3) {
/* enctype is multipart/form-data */
for (nFile = 0; nFile < oField.files.length; nFile++) {
oFile = oField.files[nFile];
oSegmReq = new FileReader();
/* (custom properties:) */
oSegmReq.segmentIdx = this.segments.length;
oSegmReq.owner = this;
/* (end of custom properties) */
oSegmReq.onload = pushSegment;
this.segments.push("Content-Disposition: form-data; name="" + oField.name + ""; filename=""+ oFile.name + ""\r\nContent-Type: " + oFile.type + "\r\n\r\n");
this.status++;
oSegmReq.readAsBinaryString(oFile);
}
} else {
/* enctype is application/x-www-form-urlencoded or text/plain or method is GET: files will not be sent! */
for (nFile = 0; nFile < oField.files.length; this.segments.push(fFilter(oField.name) + "=" + fFilter(oField.files[nFile++].name)));
}
} else if ((sFieldType !== "RADIO" && sFieldType !== "CHECKBOX") || oField.checked) {
/* field type is not FILE or is FILE but is empty */
this.segments.push(
this.technique === 3 ? /* enctype is multipart/form-data */
"Content-Disposition: form-data; name="" + oField.name + ""\r\n\r\n" + oField.value + "\r\n"
: /* enctype is application/x-www-form-urlencoded or text/plain or method is GET */
fFilter(oField.name) + "=" + fFilter(oField.value)
);
}
}
processStatus(this);
}
return function (oFormElement) {
if (!oFormElement.action) { return; }
new SubmitRequest(oFormElement);
};
})();
[].forEach.call(document.querySelectorAll("form"), function(el) {
el.addEventListener("submit", AJAXSubmit(this));
});
Alles anzeigen
Ein bisschen minimiert:
if(!XMLHttpRequest.prototype.sendAsBinary){XMLHttpRequest.prototype.sendAsBinary=function(a){var b=a.length,c=new Uint8Array(b);for(var i=0;i<b;i++){c[i]=a.charCodeAt(i)&0xff;}
this.send(c);};}
var AJAXSubmit=(function(){function d(){alert(this.responseText);}
function e(f){var g=new XMLHttpRequest();g.submittedData=f;g.onload=d;if(f.technique===0){g.open("get",f.receiver.replace(/(?:\?.*)?$/,f.segments.length>0?"?"+f.segments.join("&"):""),true);g.send(null);}else{g.open("post",f.receiver,true);if(f.technique===3){var h="---------------------------"+Date.now().toString(16);g.setRequestHeader("Content-Type","multipart\/form-data; boundary="+h);g.sendAsBinary("--"+h+"\r\n"+f.segments.join("--"+h+"\r\n")+"--"+h+"--\r\n");}else{g.setRequestHeader("Content-Type",f.contentType);g.send(f.segments.join(f.technique===2?"\r\n":"&"));}}}
function j(f){if(f.status>0){return;}
e(f);}
function k(l){this.owner.segments[this.segmentIdx]+=l.target.result+"\r\n";this.owner.status--;j(this.owner);}
function m(n){return n.replace(/[\s\=\\]/g,"\\$&");}
function o(p){var q,r,s,t,u,v=p.method.toLowerCase()==="post";this.contentType=v&&p.enctype?p.enctype:"application\/x-www-form-urlencoded";this.technique=v?this.contentType==="multipart\/form-data"?3:this.contentType==="text\/plain"?2:1:0;this.receiver=p.action;this.status=0;this.segments=[];var w=this.technique===2?m:escape;for(var i=0;i<p.elements.length;i++){s=p.elements[i];if(!s.hasAttribute("name")){continue;}
r=s.nodeName.toUpperCase()==="INPUT"?s.getAttribute("type").toUpperCase():"TEXT";if(r==="FILE"&&s.files.length>0){if(this.technique===3){for(q=0;q<s.files.length;q++){u=s.files[q];t=new FileReader();t.segmentIdx=this.segments.length;t.owner=this;t.onload=k;this.segments.push("Content-Disposition: form-data; name=""+s.name+""; filename=""+u.name+""\r\nContent-Type: "+u.type+"\r\n\r\n");this.status++;t.readAsBinaryString(u);}}else{for(q=0;q<s.files.length;this.segments.push(w(s.name)+"="+w(s.files[q++].name)));}}else if((r!=="RADIO"&&r!=="CHECKBOX")||s.checked){this.segments.push(this.technique===3?"Content-Disposition: form-data; name=""+s.name+""\r\n\r\n"+s.value+"\r\n":w(s.name)+"="+w(s.value));}}
j(this);}
return function(x){if(!x.action){return;}
new o(x);};})();[].forEach.call(document.querySelectorAll("form"),function(el){el.addEventListener("submit",AJAXSubmit(this));});
Alles anzeigen