Whether it is PHP or other server-side scripts, they provide file upload function, which is relatively simple to implement. Using JavaScript to cooperate, Ajax file upload can be realized. Although jQuery itself does not provide such simplified functions, there are many plug-ins that can be implemented. Among them, ajaxfileupload.js provided by Phpletter.com is a lightweight plug-in, and the writing method is very similar to the global method $.post() provided by jQuery, and is simple and easy to use.
However, this plug-in is too simplified. In addition to providing the path to upload files, it cannot pass additional values to the background server. So, I modified the script and added a data object parameter.
1. Principle
I am using PHP as a server-side script here. Almost every book with less PHP will mention how to use the move_uploaded_file() method to upload files, I won't go into details here. What I want to say is to use the principle of Ajax upload.
Because I have been using the jQuery library, when I think of Ajax, my first reaction is to try the $.post() method, use each selector to get the value value in the file file box, and then submit it to the background server. Of course, it turned out that this was not possible. (Because of this problem, I have also checked a lot of information and provided many scripts such as ASP on the Internet. I really don’t know what to say.)
Back to the topic, it is actually not difficult to upload Ajax, and there are many methods. The ajaxfileupload.js plugin for Phpletter.com mentioned in this article is the way to use iframes. This is also a common method when uploading without refreshing the page without using JavaScript scripts. (This method is used to write logs in the bo-blog background of this blog)
The ajaxfileupload.js plug-in is also very simple. It first uses the jQuery selector to obtain the file path value in the file upload box, then dynamically create an iframe, and create a new file file box inside, providing a post method to submit it to the background. Finally, return to the results to the front desk.
2. Use
The use of ajaxfileupload.js plugin is very simple.
The front desk HTML code is similar:
<script type="text/javascript">$(#buttonUplod).click(function () { $.ajaxFileUpload ({ url:'doajaxfileupload.php', //The server where you handle uploading the file is secureuri:false, //The ID value corresponding to the file in the page processing code fileElementId:'img', dataType: 'json', //Return data types: text, xml, json, html, scritp, jsonp five successes: function (data) { alert(data.file_infor); } })});</script><input id="img" type="file" size="45" name="img" ><button id="buttonUpload" onclick="return ajaxFileUpload();">Upload</button>Background doajaxfileupload.php script:
<?php $upFilePath = "../attachment/";$ok=@move_uploaded_file($_FILES['img']['tmp_name'],$upFilePath); if($ok === FALSE){ echo json_encode('file_infor'=>'Upload failed'); }else{ echo json_encode('file_infor'=>'Uploaded successfully'); }?>For testing, you can save the passed variable value in a similar way to the following:
$file_info = var_export($_FILES,true);
$ok = file_put_contents("../attachment/file_info.txt",$file_info);
if ($ok) exit(json_encode('file_infor'=>'Uploaded successfully'));
exit (json_encode('file_infor'=>'Upload failed'));
※ Notice
Please note the marks in the HTML code file box:
1. id='img' is used to identify fileElementId:'img' of the ajaxfileupload.js plugin. The jQuery selector will use this string to obtain the value of the text box;
2. name='img' is used to read the uploaded file data through $_FILES['img'] when submitting it to a background script through post. If this value is not available, the $_FILES variable is empty;
Therefore, both of these two values are indispensable and cannot be confused.
3. Support additional parameters
Sometimes, we need to handle uploaded files based on certain variables in the background. For example, update the file. At this time, you need to pass some additional parameters to the same stage. So, I modified the ajaxfileupload.js plugin:
addOtherRequestsToForm: function(form,data){ // add extra parameter var originalElement = $('<input type="hidden" name="" value="">'); for (var key in data) { name = key; value = data[key]; var cloneElement = originalElement.clone();cloneElement.attr({'name':name,'value':value}); $(cloneElement).appendTo(form); } return form;}, ajaxFileUpload: function(s) { // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout s = jQuery.extend({}, jQuery.ajaxSettings, s); var id = new Date().getTime() var form = jQuery.createUploadForm(id, s.fileElementId); if ( s.data ) form = jQuery.addOtherRequestsToForm(form,s.data); var io = jQuery.createUploadIframe(id, s.secureuri);The red marking part is what I added. This way I can pass additional parameters in the foreground HTML section through code like below:
url:'doajaxfileupload.php', //The server where you handle uploading files
secureuri:false, //The ID value corresponding to the file in the page processing code
data:{'test':'test','ok':'ok'}, //Passed in an object, and the content part can enter the variable value of JavaScript
fileElementId:'img',
The background processing script is:
array_push($_FILES,$_REQUEST);$file_info = var_export($_FILES,true);$ok = file_put_contents("../attachment/file_info.txt",$file_info);if ($ok) exit(json_encode('file_infor'=>'Uploaded successfully')); exit (json_encode('file_infor'=>'Upload failed'));It can be seen that the principle is very simple, which is to add the additional data object content to the form under the iframe, pass it to the background PHP script, and obtain these values with variables such as $_REQUEST.
The file_info.txt content retained in the background output is as follows:
array (
'file' =>
array (
'name' => 'firefox-java.txt',
'type' => 'text/plain',
'tmp_name' => 'D://Tools//xampp//tmp//phpED45.tmp',
'error' => 0,
'size' => 250,
),
0 =>
array (
'test' => 'test',
'ok' => 'ok',
'PHPSESSID' => 'e379fd4fb2abca6e802a1302805a5535',
),
)
ajaxfileupload.js:
jQuery.extend({ createUploadIframe: function(id, uri) { //create framevar frameId = 'jUploadFrame' + id;if(window.ActiveXObject) {var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');if(typeof uri== 'boolean'){io.src = 'javascript:false';}else if(typeof uri== 'string'){io.src = uri;}}else {var io = document.createElement('iframe');io.id = frameId;io.name = frameId;}io.style.position = 'absolute';io.style.top = '-1000px';io.style.left = '-1000px'; document.body.appendChild(io); return io }, createUploadForm: function(id, fileElementId) { //create form var formId = 'jUploadForm' + id; var fileId = 'jUploadFile' + id; var form = $('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>'); var oldElement = $('#' + fileElementId); var newElement = $(oldElement).clone(); $(oldElement).attr('id', fileId); $(oldElement).before(newElement); $(oldElement).appendTo(form); //set attributes $(form).css('position', 'absolute'); $(form).css('top', '-1200px'); $(form).css('left', '-1200px'); $(form).appendTo('body'); return form; }, addOtherRequestsToForm: function(form,data) { // add extra parameter var originalElement = $('<input type="hidden" name="" value="">'); for (var key in data) { name = key; value = data[key]; var cloneElement = originalElement.clone(); cloneElement.attr({'name':name,'value':value}); $(cloneElement).appendTo(form); } return form; }, ajaxFileUpload: function(s) { // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout s = jQuery.extend({}, jQuery.ajaxSettings, s); var id = new Date().getTime() var form = jQuery.createUploadForm(id, s.fileElementId); if ( s.data ) form = jQuery.addOtherRequestsToForm(form,s.data); var io = jQuery.createUploadIframe(id, s.secureuri); var frameId = 'jUploadFrame' + id; var formId = 'jUploadForm' + id; // Watch for a new set of requests if ( s.global && ! jQuery.active++ ) { jQuery.event.trigger( "ajaxStart" ); } var requestDone = false; // Create the request object var xml = {} if ( s.global )jQuery.event.trigger("ajaxSend", [xml, s]); // Wait for a response to come back var uploadCallback = function(isTimeout) { var io = document.getElementById(frameId);try { if(io.contentWindow) { xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null; xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document; }else if(io.contentDocument) { xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null; xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document; } }catch(e) { jQuery.handleError(s, xml, null, e); }if ( xml || isTimeout == "timeout") { requestDone = true;var status;try {status = isTimeout != "timeout" ? "success" : "error";// Make sure that the request was successful or notmodifiedif ( status != "error" ) {// process the data (runs the xml through httpData regardless of callback)var data = jQuery.uploadHttpData( xml, s.dataType ); // If a local callback was specified, fire it and pass it the dataif ( s.success )s.success( data, status );// Fire the global callbackif( s.global )jQuery.event.trigger( "ajaxSuccess", [xml, s] );} elsejQuery.handleError(s, xml, status);} catch(e) {status = "error";jQuery.handleError(s, xml, status, e);} // The request was completeif( s.global )jQuery.event.trigger( "ajaxComplete", [xml, s] ); // Handle the global AJAX counterif ( s.global && ! --jQuery.active )jQuery.event.trigger( "ajaxStop" ); // Process result ( s.complete )s.complete(xml, status); jQuery(io).unbind() setTimeout(function() { try { $(io).remove(); $(form).remove(); } catch(e) { jQuery.handleError(s, xml, null, e); } }, 100) xml = null } } // Timeout checker if ( s.timeout > 0 ) {setTimeout(function(){// Check to see if the request is still happeningif( !requestDone ) uploadCallback( "timeout" );}, s.timeout); } try { // var io = $('#' + frameId); var form = $('#' + formId); $(form).attr('action', s.url); $(form).attr('method', 'POST'); $(form).attr('target', frameId); if(form.encoding) {form.encoding = 'multipart/form-data'; }else { form.enctype = 'multipart/form-data';} $(form).submit(); } catch(e) { jQuery.handleError(s, xml, null, e); }if(window.attachEvent){document.getElementById(frameId).attachEvent('onload', uploadCallback); } else{document.getElementById(frameId).addEventListener('load', uploadCallback, false); } return {abort: function () {}}; }, uploadHttpData: function( r, type ) { var data = !type; data = type == "xml" || data ? r.responseXML : r.responseText; // If the type is "script", eval it in global context if ( type == "script" )jQuery.globalEval( data ); // Get the JavaScript object, if JSON is used. if ( type == "json" )eval( "data = " + data ); // evaluate scripts within html if ( type == "html" )jQuery("<div>").html(data).evalScripts(); //alert($('param', data).each(function(){alert($(this).attr('value'));})); return data; }})