Ajax File Upload Response Handling

前端之家收集整理的这篇文章主要介绍了Ajax File Upload Response Handling前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Ajax File Upload Response Handling

A while ago,I wrote an article onAjax File Uploading-the method of uploading a file without refreshing the page using a hidden iframe. Since then people wanted to know how toget information about the uploaded file back into the javascript application. Consider this the second part of that article - this post will tell you how to get the information about the uploaded file in javascript.

A Sample Application

For example,say you arebuilding a photo gallery. When a user uploads an image(using the above mentioned ajax method),you want toget its name and file size from the server side. First,lets create the Javascript uploading script(for explanation on this part,see theAjax File Upload article)...

The Code

<script type="text/javascript">
function init() {
	document.getElementById("file_upload_form").onsubmit=function() {
		document.getElementById("file_upload_form").target = "upload_target";
	}
}
</script>

<form id="file_upload_form" method="post" enctype="multipart/form-data" action="upload.PHP">
<input name="file" id="file" size="27" type="file" /><br />
<input type="submit" name="action" value="Upload Image" /><br />
<iframe id="upload_target" name="upload_target" src="" style="width:100px;height:100px;border:1px solid #ccc;"></iframe>
</form>
<div id="image_details"></div>

And theserver side(PHPin this case) script will look something like this...

<?PHP
list($name,$result) = upload('file','image_uploads','jpg,jpeg,gif,png');
if($name) { // Upload Successful
	$details = stat("image_uploads/$name");
	$size = $details['size'] / 1024;
	print json_encode(array(
		"success" => $result,
		"failure"	=>	false,"file_name"	=>	$name,// Name of the file - JS should get this value
		"size"		=>	$size	// Size of the file - JS should get this as well.
	));
} else { // Upload Failed for some reason.
	print json_encode(array(
		"success"	=>	false,"failure"	=>	$result,));
}

Here we are printing the data that should be given to JS directly into the iframe. Javascript canaccess this data by accessing the iframe's DOM. Lets add that part to the JS code...

function init() {
	document.getElementById("file_upload_form").onsubmit=function() {
		document.getElementById("file_upload_form").target = "upload_target";
		document.getElementById("upload_target").onload = uploadDone; //This function should be called when the iframe has compleated loading // That will happen when the file is completely uploaded and the server has returned the data we need.
	}
}

function uploadDone() { //Function will be called when iframe is loaded var ret = frames['upload_target'].document.getElementsByTagName("body")[0].innerHTML; var data = eval("("+ret+")"); //Parse JSON // Read the below explanations before passing judgment on me if(data.success) { //This part happens when the image gets uploaded. document.getElementById("image_details").innerHTML = "<img src='image_uploads/" + data.file_name + "' /><br />Size: " + data.size + " KB"; } else if(data.failure) { //Upload Failed - show user the reason. alert("Upload Failed: " + data.failure); } }

Explanation

Lets see whats happening here - a play by play commentary...

document.getElementById("upload_target").onload = uploadDone;

Set anevent handler that will be called when the iframe has compleated loading. That will happen when the file is completely uploaded and the server has returned the data we need. Now lets see the functionuploadDone().

var ret = frames['upload_target'].document.getElementsByTagName("body")[0].innerHTML;
var data = eval("("+ret+")");

These two lines are an eyesore. No - it goes beyond 'eyesore' - this is an abomination. If these lines causes you to gouge out your eyes and run for the hills,I can understand completely. I had to wash my hands after writing those lines. Twice.

var ret = frames['upload_target'].document.getElementsByTagName("body")[0].innerHTML;

This willget the data the server side script put in the iframe. This line cannot be avoided as far as I know. You can write it in different ways - but in the end,you will have to take the innerHTML or the nodeValue or something of the body element of the iframe. I used the smallest code in the sample. Even if you specify the Content type of the iframe page as text/plain,the browser will 'domify' it.

One other thing -inframes['upload_target']the 'upload_target' is the name of the iframe - not the ID. Its a gotcha you need to be aware of.

var data = eval("("+ret+")");

Thankfully,this line can be avoided - you can use some other format(in this particular case the best format might be plain HTML) so that you don't have to parse a string that comes out of innerHTML. Or you can useCSV. Or plain text. OrJSONas we are doing right now - just parse it without usingeval(). Reason I choose it? Smallest code - and easier to understand.

Now we have a working system. The files are uploaded and data reaches the client side. Everything works perfectly. Oh,how I wish I could say that. But nooo - the nightmare of every javascript developer rears its ugly head again...

Internet Explorer

Internet Explorer,also known as IE,also known as the Beast,again manages to mess things up. Theydon't support the onload event for iframe. So the code...

document.getElementById("upload_target").onload = uploadDone;

will not work. WILL. NOT. WORK. Thanks IE,thanks very much.

So,what do we do? We use a small hack. We put a script tag inside the iframe with a onload event that calls the uploadDone() of the top frame. So now the server side script looks like this...

<html>
<head>
<script type="text/javascript">
function init() { if(top.uploadDone) top.uploadDone(); //top means parent frame. } window.onload=init;
</script>
<body>
<?PHP
list($name,$result) = upload('file',png');
if($name) { // Upload Successful
	// Put the PHP content from the last code sample here here
}
?>
</body>
</html>

Okay - now we have a IE-proof working system. Upload an image using the below demo application to see it in action.

If you have a better way of doing this,please,PLEASE let me know. I feel dirty doing it this way.

See it in Action

原文链接:https://www.f2er.com/ajax/163241.html

猜你在找的Ajax相关文章