• 异步上传文件解决方法


    一、

    通过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>
  • 相关阅读:
    【原生】数组去重的方法
    【原生】详解Javascript中prototype属性(推荐)
    【原生】 ES5中的构造函数与 ES6 中的类 及构造函数的理解
    【react】React学习:状态(State) 和 属性(Props)
    【react】 flux 了解
    【请求数据】fetch 的get请求和post请求
    【react】 使用create-react-app创建react项目,运行npm run eject报错: 暴露webpack配置文件
    package.json 文件的介绍
    802.11协议精读1:学习资料整理(转)
    ns2之包结构解析
  • 原文地址:https://www.cnblogs.com/linzheng/p/1865671.html
Copyright © 2020-2023  润新知