zoukankan      html  css  js  c++  java
  • 异步上传文件解决方法

    一、

    通过iframe来实现无刷新的的文件上传,其实是有刷新的,只是在iframe里面隐藏了而已

    简单的原理说明:

    <form id="form1" method="post" action="upload.do" enctype="multipart/form-data"  target="uploadframe" >
    <input type="file" id="upload" name="文件上传" />
    </form>

    <iframe id="uploadframe" name="result_frame"   style="visibility:hidden;"></iframe>

    form里面的target要与iframe里面的id的值相等,指示是form相应了post事件,也就是post时间相应的时候刷新的是iframe而不是整个页面。

    二、

    利用jQuery的插件AjaxFileUpload 可以简单地实现这个异步的上传的效果      插件地址: http://www.phpletter.com/Our-Projects/AjaxFileUpload/

     <script type="text/javascript" language="javascript" src="js/jquery.js"></script>

     <script type="text/javascript" language="javascript" src="js/ajaxfileupload.js"></script>

    代码
    function ajaxFileUpload()
    {
    $(
    "#loading")
    .ajaxStart(
    function(){
    $(
    this).show();
    })
    .ajaxComplete(
    function(){
    $(
    this).hide();
    });

    $.ajaxFileUpload
    (
    {
    url:
    'Upload.ashx',
    secureuri:
    false,
    fileElementId:
    'fileToUpload',
    dataType:
    'json',
    success:
    function (data, status)
    {
    if(typeof(data.error) != 'undefined')
    {
    if(data.error != '')
    {
    alert(data.error);
    }
    else
    {
    alert(data.msg);
    }
    }
    },
    error:
    function (data, status, e)
    {
    alert(e);
    }
    }
    )

    return false;

    }

    <input id="fileToUpload" type="file" size="45" name="fileToUpload">

    <input type="button" id="buttonUpload" onclick="return ajaxFileUpload();">
           上传</input>

    Upload.ashx

    代码
    if (Request.Files.Count > 0)
    {
    HttpPostedFile file
    = Request.Files[0];
    string msg = "";
    string error = "";
    if (file.ContentLength == 0)
    error
    = "文件长度为0";
    else
    {
    file.SaveAs(Server.MapPath(
    "file") + "\\" + Path.GetFileName(file.FileName));
    msg
    = "上传成功";
    }
    string result = "{ error:'" + error + "', msg:'" + msg + "'}";
    Response.Write(result);
    Response.End();
    }

    PS:ajaxfileupload.js代码

    代码
    jQuery.extend({

    createUploadIframe:
    function(id, uri)
    {
    //create frame
    var 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;
    },

    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);
    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 notmodified
    if ( 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 data
    if ( s.success )
    s.success( data, status );

    // Fire the global callback
    if( s.global )
    jQuery.event.trigger(
    "ajaxSuccess", [xml, s] );
    }
    else
    jQuery.handleError(s, xml, status);
    }
    catch(e)
    {
    status
    = "error";
    jQuery.handleError(s, xml, status, e);
    }

    // The request was completed
    if( s.global )
    jQuery.event.trigger(
    "ajaxComplete", [xml, s] );

    // Handle the global AJAX counter
    if ( s.global && ! --jQuery.active )
    jQuery.event.trigger(
    "ajaxStop" );

    // Process result
    if ( 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 happening
    if( !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;
    }
    })

     三、纯iframe实现上传

    upload.ashx

    代码
    //<%@ WebHandler Language="C#" Class="upload" %>

    using System;
    using System.Web;

    public class upload : IHttpHandler {
    private string Js(string v) {//此函数进行js的转义替换的,防止字符串中输入了'后造成回调输出的js中字符串不闭合
    if (v == null) return "";
    return v.Replace("'", @"\'");
    }
    //下面就是一个简单的示例,保存上传的文件,如果要验证上传的后缀名,得自己写,还有写数据库什么的
    public void ProcessRequest (HttpContext context) {
    HttpRequest Request
    = context.Request;
    HttpResponse Response
    = context.Response;
    HttpServerUtility Server
    = context.Server;
    //指定输出头和编码
    Response.ContentType = "text/html";
    Response.Charset
    = "utf-8";

    HttpPostedFile f
    = Request.Files["upfile"];//获取上传的文件
    string des = Request.Form["des"]//获取描述
    ,newFileName=Guid.NewGuid().ToString();//使用guid生成新文件名

    if (f.FileName == "")//未上传文件
    Response.Write("<script>parent.UpdateMsg('','');</script>");//输出js,使用parent对象得到父页的引用
    else { //保存文件
    newFileName += System.IO.Path.GetExtension(f.FileName);//注意加上扩展名
    try {
    f.SaveAs(Server.MapPath(
    "~/uploads/" + newFileName));//如果要保存到其他地方,注意修改这里

    //调用父过程更新内容,注意要对des变量进行js转义替换,防止字符串不闭合提示错误
    Response.Write("<script>parent.UpdateMsg('" +Js(des)+ "','" + newFileName + "')</script>");
    }
    catch {
    Response.Write(
    "<script>alert('保存文件失败!\\n请检查文件夹是否有写入权限!');</script>");//如果保存失败,输出js提示保存失败
    }

    }
    }

    public bool IsReusable {
    get {
    return false;
    }
    }

    }

    test.htm

    代码
    <!!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>
    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <title>使用隐藏的Iframe实现ajax无刷新上传</title>
    </head>
    <body>
    <script type="text/javascript">
    function UpdateMsg(des,filename){//此函数用来提供给提交到的页面如upload.ashx输出js的回调,更新当前页面的信息
    if(filename==''){alert('未上传文件!');return false;}
    document.getElementById(
    'ajaxMsg').innerHTML='你在表单中输入的“文件描述”为:'+des+'<br/>'
    +'上传的图片为:<a href="uploads/'+filename+'" target="_blank">'+filename+'</a>';
    }

    function check(f){
    if(f.des.value==''){
    alert(
    '请输入文件描述!');f.des.focus();return false;
    }
    if(f.upfile.value==''){
    alert(
    '请选择文件!');f.upfile.focus();return false;
    }
    }
    </script>
    <!--隐藏的iframe来接受表单提交的信息-->
    <iframe name="ajaxifr" style="display:none;"></iframe>
    <!--这里设置target="ajaxifr",这样表单就提交到iframe里面了,和平时未设置target属性时默认提交到当前页面-->
    <!--注意一点的是使用iframe时在提交到的页面可以直接输出js来操作父页面的信息,一般的ajax提交文本信息时你需要返回信息,如果是js信息你还得eval下-->
    <form method="post" enctype="multipart/form-data" action="upload.ashx" target="ajaxifr" onsubmit="return check(this)">
    文件描述:
    <input type="text" name="des" /><br >
    选择文件:
    <input type="file" name="upfile" /><br >
    <input type="submit" value="提交" />
    </form>
    <!--放入此div用来实现上传的结果-->
    <div id="ajaxMsg"></div>
    </body>
    </html>
  • 相关阅读:
    tile38 复制配置
    The Guardian’s Migration from MongoDB to PostgreSQL on Amazon RDS
    tile38 一款开源的geo 数据库
    sqler sql 转rest api 的docker 镜像构建(续)使用源码编译
    sqler sql 转rest api javascript 试用
    sqler sql 转rest api redis 接口使用
    sqler sql 转rest api 的docker image
    sqler sql 转rest api 的工具试用
    apache geode 试用
    benthos v1 的一些新功能
  • 原文地址:https://www.cnblogs.com/linzheng/p/1865671.html
Copyright © 2011-2022 走看看