这里用的是一个隐藏的iframe,这样可以让form表单提交到这个iframe里面,用户就看不到页面的刷新了

前段时间在解决ajax上传文件时折腾了好一阵。直接用$.post上传文本信息肯定是没有问题的。但是$.post直接上传图片是不可行的。

后来看到网上的一些解决方案,有现成的ajax上传文件的封装的方法也有利用flash的。flash确实是个好方法 但是不是每个人都会flash的而且下载下来现成的方法要做修改也不是件易事,且文件相对较大。

最后只好模拟iframe来实现。发现相当的简单。

<iframe name="ajaxUpload" style="display:none"></iframe>

<form name="from1" id="from1" method="post" action="url"  enctype="multipart/form-data" target="ajaxUpload">     这里是重点。要上传文件enctype这个属性不可少,target的值改为iframe的name的值。

<table>

<tr>

<td>附件:</td>

<td><input type="file" id="document" name="document"/></td>

</tr>

</table>

</form>

上面是HTML

下面写一下js代码,我是用的jQuery所以在用的时候载入jquery的库是必不可少的。

$(function(){

if($.browser.msie){

window.form1.submit();}else{

$("#form1").submit();}

});

//这里是做了一个浏览器版本的判断,因为IE是不太符合规范的一个浏览器,尤其是IE6。IE6是不直接支持$("#idName").submit();这种方式的。

然后在服务端要怎么着呢,而且还得返回一个值,直接submit是无法返回值的

public void Upload()

{

HttpPostedBase ff=Request.Files["document"];//这里是获取上传的文件流,也可以用索引值来表示如果是多个文件的话

string fileName=System.DateTime.Now+ff.FileName.ToString();   //这里取出来的文件名是没有后缀的,所以要保存的话还需要取出文件拓展名。这里就不写过细,只是为描述这样一个思路。

try{

SaveAs(documentPath+fileName+extendtionName);

Response.Write("<script type='text/javascript' type='language'>parent.window.callBackMethod('上传成功');</scrpt>");

}

catch

{

Response.Write("<script type='text/javascript' type='language'>parent.window.callBackMethod('上传失败');</scrpt>");  //parent.window.methodName();这个是JS调用父页的方法。因为现在模拟一个iframe上传文件,这个iframe的作用就是一个中间站的作用。在父页点击上传后通过target会将页面文档流传入iframe中再上传服务端作处理。服务端有响应之后然后再在iframe里面显示出来,而不是直接在父页面显示出结果。这里可能就是一个alert()弹出一个对话框提示一下,如果是这样那么不调父页方法也行。如果想把这提示的内容丰富一点比如弹出个类似人人网的蓝色的对话框之类的。

}

}

模拟iframe其实是页面局部更新,但是页面中的这个iframe没有内容而且还是不显示的,所以它刷新了完全不会影响到整个页面。

--------------------------------------------------------------------------------------------------------------------------------------------------------------

最近看了一些jQuery即时上传的插件,总算看懂了些门路。现将其最为核心的一部分抽取出来,以期用最简单的例子来说明jQuery图片即时上传的原理。

  首先本用例一共包含3个文件:

    1、上传面板HTML文件。

    2、上传处理PHP文件。

    3、jQuery库。

  第一、上传面板HTML文件(index.html)。

其主要包含了jQuery库、即时上传所需js、表单和iframe框架。下面是其源码,其中已附详细注释。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>jQuery Upload Image</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="zh-CN" />
<!--<script type="text/javascript" src="jquery-1.6.2.min.js"></script>--> <!-- 本地jquery库-->
<script type="text/javascript" src="http://files.cnblogs.com/Zjmainstay/jquery-1.6.2.min.js"></script>
</head>
<body>
<style>
#exec_target{display:none;width:0;height:0;}
#feedback{width:1200px;margin:0 auto;}
#feedback img{float:left;width:300px;height:300px;}
</style>
<script type="text/javascript">
$(document).ready(function(){
//选择文件成功则提交表单
$("#upload_file").change(function(){
if($("#upload_file").val() != '') $("#submit_form").submit();
});
//iframe加载响应,初始页面时也有一次,此时data为null。
$("#exec_target").load(function(){
var data = $(window.frames['exec_target'].document.body).find("textarea").html();
//若iframe携带返回数据,则显示在feedback中
if(data != null){
$("#feedback").append(data.replace(/&lt;/g,'<').replace(/&gt;/g,'>'));
$("#upload_file").val('');
}
});
});
</script>
<form id="submit_form" method="post" action="submit_form_process.php" target="exec_target" enctype="multipart/form-data">
<input type="file" name="upload_file" id="upload_file"> <!-- 添加上传文件 -->
</form>
<iframe id="exec_target" name="exec_target"></iframe> <!-- 提交表单处理iframe框架 -->
<div id="feedback"></div> <!-- 响应返回数据容器 -->
</body>
</html>

第二、上传处理PHP文件(submit_form_process.php)。

    其主要包含了图片文件的简单上传,及返回图片标签<img>,其中存储刚上传的图片。下面是其源码。

<?php
//header('content-type:text/html charset:utf-8'); /* 这句要删除,否则可能会导致IE下回传HTML变成下载 */
//不存在当前上传文件则上传
if(!file_exists($_FILES['upload_file']['name'])) move_uploaded_file($_FILES['upload_file']['tmp_name'],iconv('utf-8','gb2312',$_FILES['upload_file']['name']));
//输出图片文件<img>标签
echo "<textarea><img src='{$_FILES['upload_file']['name']}'/></textarea>";
//End_php

总结之原理透析:

    讲到jQuery即时上传,不知道其原理的人第一想法一般都是使用AJAX(补注:当时不知道有FormData对象),我也尝试过。但是,由于上传文件不同于一般数据的POST,它需要表单form的提交来完成。因此,jQuery上传插件也是将<input type="file">的数据转至一个新生的form当中将其提交,而表单的target指向新生的iframe,在iframe中做表单提交后的处理,完成后iframe会重新加载并包含处理结果,通过iframe的load事件便可捕捉并获取处理结果,回传至原表单所在的页面(feedback)中,实现jQuery即时上传的效果。而在表单提交的时候,为了实现选择文件后即时提交表单,则使用了input标签的change事件(index.html L19-21),只要选择了文件,input的值就会发生变化,此时就可以提交表单进行处理了。

软件包下载:最简单的jQuery即时上传示例

/***************************************   追加  ***************************************/

受@东方翔 评论提示,测试了一下$.ajax 的FormData对象,然后发现成功了(FF、Chrome测试成功),嘿嘿~下面是源码,控制文件为submit_form_process.php不变。

特别的:contentType: false,
            processData: false,

这两个参数是必须的。

缺少contentType: false,$_FILES值为空。

缺少processData: false,FF控制台报错:“NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object”,直接不能运行。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>FormData</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="zh-CN" />
<script type="text/javascript" src="http://files.cnblogs.com/Zjmainstay/jquery-1.6.2.min.js"></script>
</head>
<body>
<style>
#feedback{width:1200px;margin:0 auto;}
#feedback img{float:left;width:300px;height:300px;}
</style>
<div>
<!-- 点击图片添加文件方式 -->
<img src="http://f7-preview.awardspace.com/zjmainstay.co.cc/jQueryExample/jquery_upload_image/files/addfile.jpg" onclick="getElementById('inputfile').click()" title="点击添加图片" alt="点击添加图片">
<input type="file" name="image" style="opacity:0;filter:alpha(opacity=0);" id="inputfile"/>
</div>
<div id="feedback"></div> <!-- 响应返回数据容器 -->
<script type="text/javascript">
$(document).ready(function(){
$("#inputfile").change(function(){
//创建FormData对象
var data = new FormData();
//为FormData对象添加数据
//
$.each($('#inputfile')[0].files, function(i, file) {
data.append('upload_file', file);
});
$.ajax({
url:'submit_form_process.php',
type:'POST',
data:data,
cache: false,
contentType: false, //不可缺
processData: false, //不可缺
success:function(data){
data = $(data).html();
if($("#feedback").children('img').length == 0) $("#feedback").append(data.replace(/&lt;/g,'<').replace(/&gt;/g,'>'));
else $("#feedback").children('img').eq(0).before(data.replace(/&lt;/g,'<').replace(/&gt;/g,'>'));
}
});
});
});
</script>
</body>
</html>

/***************************************   追加2  ***************************************/

多图上传实现(独立于上面两个版本的文件):

     1、index.html文件

功能:点击图片添加文件、添加多个文件、即时上传文件、显示上传文件反馈信息。

包含技术:

1)$.ajax

2)$.ajax 发送FormData对象

3)input multiple="multiple"上传多个文件

4)img onclick="getElementById('inputfile').click()" 点击图片实现添加文件操作

5)input type="file" 样式:height:0;width:0;z-index: -1;隐藏添加文件按钮(Chrome下使用display:none会导致点击失效)

源码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Easy Ajax FormData Upload Multiple Images</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="zh-CN" />
<script type="text/javascript" src="http://files.cnblogs.com/Zjmainstay/jquery-1.6.2.min.js"></script>
</head>
<body>
<style>
#feedback{width:1200px;margin:0 auto;}
#feedback img{float:left;width:300px;height:300px;}
#ZjmainstaySignaturePicture,#addpicContainer{float:left;width: 100%;}
#addpicContainer{margin-left:5px;}
#ZjmainstaySignaturePicture img{width: 535px;}
#addpicContainer img{float: left;}
.loading{display:none;background:url("http://f7-preview.awardspace.com/zjmainstay.co.cc/jQueryExample/jquery_upload_image/files/ui-anim_basic_16x16.gif") no-repeat scroll 0 0 transparent;float: left;padding:8px;margin:18px 0 0 18px;}
</style>
<div id="ZjmainstaySignaturePicture"><a href="http://www.cnblogs.com/Zjmainstay"><img src="http://pic002.cnblogs.com/images/2012/383557/2012071311244097.jpg"/></a></div>
<div id="addpicContainer">
<!-- 利用multiple="multiple"属性实现添加多图功能 -->
<!-- position: absolute;left: 10px;top: 5px;只针对本用例将input隐至图片底下。-->
<!-- height:0;width:0;z-index: -1;是为了隐藏input,因为Chrome下不能使用display:none,否则无法添加文件 -->
<!-- onclick="getElementById('inputfile').click()" 点击图片时则点击添加文件按钮 -->
<img onclick="getElementById('inputfile').click()" style="cursor:pointer;border: 1px solid #AABBCC;" title="点击添加图片" alt="点击添加图片" src="http://f7-preview.awardspace.com/zjmainstay.co.cc/jQueryExample/jquery_upload_image/files/addfile.jpg">
<input type="file" multiple="multiple" id="inputfile" style="height:0;width:0;z-index: -1; position: absolute;left: 10px;top: 5px;"/>
<span class="loading"></span>
</div>
<div id="feedback"></div> <!-- 响应返回数据容器 -->
<script type="text/javascript">
$(document).ready(function(){
//响应文件添加成功事件
$("#inputfile").change(function(){
//创建FormData对象
var data = new FormData();
//为FormData对象添加数据
$.each($('#inputfile')[0].files, function(i, file) {
data.append('upload_file'+i, file);
});
$(".loading").show(); //显示加载图片
//发送数据
$.ajax({
url:'submit_form_process.php',
type:'POST',
data:data,
cache: false,
contentType: false, //不可缺参数
processData: false, //不可缺参数
success:function(data){
data = $(data).html();
//第一个feedback数据直接append,其他的用before第1个( .eq(0).before() )放至最前面。
//data.replace(/&lt;/g,'<').replace(/&gt;/g,'>') 转换html标签,否则图片无法显示。
if($("#feedback").children('img').length == 0) $("#feedback").append(data.replace(/&lt;/g,'<').replace(/&gt;/g,'>'));
else $("#feedback").children('img').eq(0).before(data.replace(/&lt;/g,'<').replace(/&gt;/g,'>'));
$(".loading").hide(); //加载成功移除加载图片
},
error:function(){
alert('上传出错');
$(".loading").hide(); //加载失败移除加载图片
}
});
});
});
</script>
</body>
</html>

2、submit_form_process.php后台处理文件

功能:对FormData中包含的$_FILES数组做处理并上传图片文件,回传反馈信息。

包含技术:

1)FormData提交至$_FILES后的结构形式

2)iconv('utf-8','gb2312',$filename) 对文件名进行转码处理

3)preg_match("/^\.(jpg|jpeg|gif|png){1}$/i", strrchr($gb_filename, '.')) 文件类型过滤

4)move_uploaded_file()上传文件

5)echo '<textarea><img....<img....</textarea>';回传反馈信息。

源码:

<?php
header('content-type:text/html charset:utf-8');
$dir_base = "./files/"; //文件上传根目录
//没有成功上传文件,报错并退出。
if(empty($_FILES)) {
echo "<textarea><img src='{$dir_base}error.jpg'/></textarea>";
exit(0);
} $output = "<textarea>";
$index = 0; //$_FILES 以文件name为数组下标,不适用foreach($_FILES as $index=>$file)
foreach($_FILES as $file){
$upload_file_name = 'upload_file' . $index; //对应index.html FomData中的文件命名
$filename = $_FILES[$upload_file_name]['name'];
$gb_filename = iconv('utf-8','gb2312',$filename); //名字转换成gb2312处理
//文件不存在才上传
if(!file_exists($dir_base.$gb_filename)) {
$isMoved = false; //默认上传失败
$MAXIMUM_FILESIZE = 1 * 1024 * 1024; //文件大小限制 1M = 1 * 1024 * 1024 B;
$rEFileTypes = "/^\.(jpg|jpeg|gif|png){1}$/i";
if ($_FILES[$upload_file_name]['size'] <= $MAXIMUM_FILESIZE &&
preg_match($rEFileTypes, strrchr($gb_filename, '.'))) {
$isMoved = @move_uploaded_file ( $_FILES[$upload_file_name]['tmp_name'], $dir_base.$gb_filename); //上传文件
}
}else{
$isMoved = true; //已存在文件设置为上传成功
}
if($isMoved){
//输出图片文件<img>标签
//注:在一些系统src可能需要urlencode处理,发现图片无法显示,
// 请尝试 urlencode($gb_filename) 或 urlencode($filename),不行请查看HTML中显示的src并酌情解决。
$output .= "<img src='{$dir_base}{$filename}' title='{$filename}' alt='{$filename}'/>";
}else {
$output .= "<img src='{$dir_base}error.jpg' title='{$filename}' alt='{$filename}'/>";
} $index++;
} echo $output."</textarea>"; //End_php

ajax上传图片文件的更多相关文章

  1. vuejs使用FormData对象,ajax上传图片文件

    我相信很多使用vuejs的朋友,都有采用ajax上传图片的需求,因为前后端分离后,我们希望都能用ajax来解决数据问题,传统的表单提交会导致提交成功后页面跳转,而使用ajax能够无刷新上传图片等文件. ...

  2. Ajax上传图片以及上传之前先预览

    手头上有几个小项目用到了easyUI,一开始决定使用easyUI就注定了项目整体上前后端分离,基本上所有的请求都采用Ajax来完成.在文件上传的时候用到了Ajax上传文件,以及图片在上传之前的预览效果 ...

  3. [Ajax] 使用Ajax异步上传图片文件(非Form表单提交)

    通过表单Form提交来上传文件的方式这里就不说了: 下面介绍,通过js中使用ajax异步上传图片文件: 新建一个html页面和一个一般处理程序即可: 涉及思路: //发送2次Ajax请求完成js异步上 ...

  4. ajaxfileUpload ajax 上传图片使用

    前台html: <div class="b-mg15 img-text" room_id="<?= $items['id'] ?>"> ...

  5. ajax上传图片

    选择文件后 ajax上传图片到后台,后台执行保存操作,返回上传的图片路径,显示到页面 需要引入ajaxfileupload.js js代码 <script type="text/jav ...

  6. 使用ajax上传图片,支持图片即时浏览,支持js图片压缩后上传给服务器

    使用ajax上传图片,支持图片即时浏览,支持js图片压缩后上传给服务器 ajax上传主要使用了 var reader = new FileReader() 此方法 js图片压缩主要是利用canvas进 ...

  7. asp.net core 通过ajax上传图片及wangEditor图片上传

    asp.net core 通过ajax上传图片 .net core前端代码,因为是通过ajax调用,首先要保证ajax能调用后台代码,具体参见上一篇.net core 使用ajax调用后台代码. 前端 ...

  8. python 全栈开发,Day75(Django与Ajax,文件上传,ajax发送json数据,基于Ajax的文件上传,SweetAlert插件)

    昨日内容回顾 基于对象的跨表查询 正向查询:关联属性在A表中,所以A对象找关联B表数据,正向查询 反向查询:关联属性在A表中,所以B对象找A对象,反向查询 一对多: 按字段:xx book ----- ...

  9. Django与Ajax,文件上传,ajax发送json数据,基于Ajax的文件上传,SweetAlert插件

    一.Django与Ajax AJAX准备知识:JSON 什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻 ...

随机推荐

  1. IIS下配置SilverLight

    在Windows 2003 IIS 6.0环境下  在Silverlight中需要使用xap.XAML文件类型,如果您想在IIS服务器上使用Silverlight 4.0程序,所以必须在IIS中注册  ...

  2. jmeter响应数据中文乱码问题

    进入jmeter安装文件目录:D:\Program File\apache-jmeter-2.13\apache-jmeter-2.13\bin\ 修改jmeter.properties文件,在最下方 ...

  3. $routeParams 实现路由指定参数

    [摘要]后台管理系统权限控制到按钮级别,将每一个资源的key绑定在url中,渲染页面的时候去根据key来获取当前页面的按钮列表. router.js angular.module("app. ...

  4. MYSQLMANAGER实例管理器总结

    好久没有写文章了,今天来看看MYSQL的实例管理器(MYSQLMANAGER).一.简单介绍:1.MySQL实例管理器(IM)是通过TCP/IP端口运行的后台程序,用来监视和管理MySQL数据库服务器 ...

  5. C# for 和 foreach的执行效率

    for和foreach哪个执行效率快,相信很多人都会说当然是foreach快啊,在我实验之前我也是这么认为的,直到今天.费话不多说,下面是测试的结果,区分Debug和Release,数据采用int[] ...

  6. the steps that may be taken to solve a feature selection problem:特征选择的步骤

    參考:JMLR的paper<an introduction to variable and feature selection> we summarize the steps that m ...

  7. 12.SpringBoot+MyBatis(XML)+Druid

    转自:https://www.cnblogs.com/MaxElephant/p/8108342.html 主要是在Spring Boot中集成MyBatis,可以选用基于注解的方式,也可以选择xml ...

  8. oled的一套stm32实验1

    详细的oled介绍:http://blog.sina.com.cn/s/blog_57ad1bd20102wtq8.html 整理自:https://www.cnblogs.com/wp2312139 ...

  9. 关于PyYAML报错问题解决

    转自:http://www.fwqtg.net/%E5%85%B3%E4%BA%8Epyyaml%E6%8A%A5%E9%94%99%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86% ...

  10. 利用OBJECT_DEFINITION函数来代码存档

    作为一名数据库管理员,在进行代码迁移之前,总是尽力给提交于开发环境的代码一个完整的面貌.但是,不得不承认,我不能保证不发生任何可能破坏开发系统的事情.当这种情况发生时,可能的补救措施是恢复到目标代码的 ...