通过IIS文件上传机制,将文件上传到文件服务器

对于需要经常上传文件的站点,为了保证文件安全性,不会把文件上传到站点下,而是把文件上传到指定的文件服务器,这里主要讲一下通过http协议上传文件。

http协议的文件上传,我目前接触到的又有两种方式:一是IIS文件上传机制,二是跨域文件上传。

本文主要讲的是IIS文件上传机制。

1.先将文件上传到应用服务器。
HTML

 <div class="layui-fluid">
        <div class="">
            <div class="col_title"> ajax上传文件到文件服务器-通过IIS上传文件</div>
            <div class="btn_file">
                <button type="button" class="layui-btn" id="btn_file" onclick="f_flie.click();"> <i class="layui-icon"></i> 上传图片</button>
                <input type="file" id="f_flie" multiple="multiple" accept="image/jpg,image/jpeg,image/png" style="display:none;" onchange="UpfileCheck(this)" />
            </div>
            <div class="preview_img_files">

            </div>

        </div>
    </div>

JS

<script src="/js/layui/layui.js"></script>
    <script src="/js/jquery/jquery-3.2.1.min.js"></script>
    <script type="text/javascript">
        var fl = 0;//文件数量
        var upload_num = 0;//文件上传索引

        //文件上传初始化
        function UpfileCheck(t) {
            fl = t.files.length;//获取文件数量
            upload_num = 0;//初始化文件上传索引

            //需要判断是否选择图片,否则第一次选择图片后,第二次选择图片取消也会触发上传
            if (fl > 0) {
                upload_mask = layer.load(1, {
                    content: '上传中...',
                    shade: [0.4, '#393D49'],
                    success: function (layero) {
                        layero.find('.layui-layer-content').css({
                            'padding-top': '39px',
                            'width': '200px',
                            'color': '#fff',
                            'text-align': 'left'
                        });
                    }
                });

                setTimeout(function () { UpfileFiles(t, upload_num); }, 500);
            }
            else {
                layer.msg('请选择需要上传的文件!');
            }
        }

        //使用file对象上传文件
        function UpfileFiles(t, f_num) {
            var imgData = new FormData();
            imgData.append('fun', 'UploadImgFilesServer');//文件上传方法名
            imgData.append('file', t.files[f_num]);//file对象
            imgData.append('src', "/upload/img/");//上传文件存放地址

            $.ajax({
                type: "POST",
                url: "/UploadFile/ashx/UploadImg.ashx",
                data: imgData,
                processData: false,//防止将发送的数据序列
                contentType: false,//默认值: true。默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 “application/x-www-form-urlencoded”。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。
                dataType: "json",
                async: false,
                success: function (data) {
                    PreviewBImg(data.ajaxresult);//预览图片
                    upload_num++;//更新文件索引
                    //文件未上传完成继续上传
                    if (upload_num < fl) {
                        UpfileFiles(t, upload_num);//继续上传
                    }
                    else {
                        layer.close(upload_mask);
                    }

                },
                error: function (event, XMLHttpRequest, ajaxOptions, thrownError) {
                    // thrownError 只有当异常发生时才会被传递 this;
                    var resStr = event.statusText
                    layer.msg("上传失败:" + resStr);
                }
            })
        }

        //预览图片
        function PreviewBImg(src) {
            var htmlimg = "<img src='" + src + "' />";
            $(".preview_img_files").append(htmlimg);
        }
    </script>

通过一般处理程序将文件上传到应用服务器

public string UploadImgFiles(HttpContext context)
        {
            HttpPostedFile files = context.Request.Files["file"];
            string src = context.Request.QueryString["src"] ?? context.Request.Form["src"];
            try
            {
                //文件上传路径+年月日
                src = src + DateTime.Now.ToString("yyMMdd") + "/";
                string uploadPath = context.Request.PhysicalApplicationPath + src;//获取文件在应用服务器存放的绝对路径
                //判断文件上传路径文件夹是否存在
                if (!Directory.Exists(uploadPath))
                {
                    Directory.CreateDirectory(uploadPath);//创建文件夹
                }
                //上传文件至应用服务器
                files.SaveAs(uploadPath + files.FileName);

                Image pic = Image.FromFile(uploadPath + files.FileName);//图片的绝对路径 
                int intWidth = pic.Width;//长度像素值 
                int intHeight = pic.Height;//高度像素值 
                pic.Dispose();//释放资源

                //文件HTTP路径,域名+端口+文件上传路径+文件名
                string httpPath = "http://" + context.Request.Url.Host + ":" + context.Request.Url.Port + src + files.FileName;

                at.ajaxDataFlag = true;
                at.ajaxresult = httpPath;
                at.ajaxString = uploadPath + files.FileName;//文件在应用服务器的绝对路径
            }
            catch (Exception ex)
            {
                at.ajaxDataFlag = false;
                at.ajaxresult = "服务器内部错误,请联系开发人员!";
                ALogOut.debug(ex.ToString());
            }
            return JsonConvert.SerializeObject(at);
        }

2.将文件上传到文件服务器

public string UploadImgFilesServer(HttpContext context)
        {
            string AuthFlag = "";//认证类型,0:window身份认证,1:匿名身份认证
            string AuthUser = "";//匿名身份认证特定用户名
            string AuthPwd = "";//匿名身份认证特定密码
            string httpurl = "";//文件上传到文件服务器的http地址
            string fileurl = "";//文件在应用服务器的绝对路径
            HttpPostedFile files = context.Request.Files["file"];
            try
            {
                //将文件先上传到应用服务器
                string JsonString = UploadImgFiles(context);
                var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(JsonString);//反序列化获取文件上传到应用服务器的结果(json字符串存在null值,转换失败解决方案)
                bool resultDataFlag = Convert.ToBoolean(result["ajaxDataFlag"].ToString());

                if (resultDataFlag == false)
                {
                    at.ajaxDataFlag = false;
                    at.ajaxresult = "服务器内部错误,请联系开发人员!";
                    return JsonConvert.SerializeObject(at);//如果文件上传到应用服务器的出错,则返回结果
                }
                else
                {
                    //如果文件上传到应用服务器成功,则上传到文件服务器
                    fileurl = result["ajaxString"].ToString();//文件在应用服务器的绝对路径

                    WebClient client = new WebClient();
                    AuthFlag = System.Configuration.ConfigurationManager.AppSettings["AuthFlag"].ToString();//认证类型,0:window身份认证,1:匿名身份认证
                    httpurl = System.Configuration.ConfigurationManager.AppSettings["PhotoFileUrl"].ToString() + files.FileName;//文件上传地址(文件服务)
                    if (AuthFlag == "1")
                    {
                        //AuthFlag:1,匿名身份认证:当应用服务器和文件服务器不在同一台服务器时,IIS会启用匿名身份认证
                        if (System.Configuration.ConfigurationManager.AppSettings["AuthUser"] == null || System.Configuration.ConfigurationManager.AppSettings["AuthPwd"] == null)
                        {
                            at.ajaxDataFlag = false;
                            at.ajaxresult = "未配置匿名身份认证特定用户名或密码,请联系管理员!";
                            return JsonConvert.SerializeObject(at);
                        }
                        else
                        {
                            AuthUser = System.Configuration.ConfigurationManager.AppSettings["AuthUser"];
                            AuthPwd = System.Configuration.ConfigurationManager.AppSettings["AuthPwd"];
                        }

                        client.Credentials = new NetworkCredential(AuthUser, AuthPwd);//发送身份认证凭证


                    }
                    else if (AuthFlag == "0")
                    {
                        //AuthFlag:0,window身份认证:在应用服务器和文件服务器在同一台服务器时,IIS会启用window身份认证
                        if (System.Configuration.ConfigurationManager.AppSettings["PhotoFileHttp"] == null || System.Configuration.ConfigurationManager.AppSettings["PhotoFileIP"] == null)
                        {
                            at.ajaxDataFlag = false;
                            at.ajaxresult = "未配置文件服务器域名或者文件服务器IP地址,请联系管理员!";
                            return JsonConvert.SerializeObject(at);
                        }
                        else
                        {
                            //如果文件服务器和应用服务器发布在同一台服务器上,并且端口相同,需要给文件服务器添加一个不一样的端口,并且将文件上传的地址中的域名替换成该IP+端口的地址
                            string PhotoFileHttp = System.Configuration.ConfigurationManager.AppSettings["PhotoFileHttp"].ToString();
                            string PhotoFileIP = System.Configuration.ConfigurationManager.AppSettings["PhotoFileIP"].ToString();
                            httpurl = httpurl.Replace(PhotoFileHttp, PhotoFileIP);
                        }
                        client.Credentials = CredentialCache.DefaultCredentials;//发送身份认证凭证
                    }
                    else
                    {
                        at.ajaxDataFlag = false;
                        at.ajaxresult = "未配置身份认证类型!";
                        return JsonConvert.SerializeObject(at);
                    }


                    //client.Headers.Add("Content-Type", "application/form-data");//注意头部必须是form-data
                    client.Headers.Add("http-method", "LOCK");
                    client.Headers.Add("http-method", "DELETE");
                    client.Headers.Add("http-method", "MOVE");
                    client.Headers.Add("http-method", "TRACE");

                    Stream postStream = client.OpenWrite(httpurl, "PUT");
                    FileStream fs = new FileStream(fileurl, FileMode.Open, FileAccess.Read);
                    BinaryReader r = new BinaryReader(fs);

                    byte[] postArray = r.ReadBytes((int)fs.Length);
                    if (postStream.CanWrite)
                    {
                        postStream.Write(postArray, 0, postArray.Length);
                    }
                    else
                    {
                        at.ajaxDataFlag = false;
                        at.ajaxresult = "文件没有权限,请联系管理员!";
                        return JsonConvert.SerializeObject(at);
                    }
                    postStream.Close();
                    client.Dispose();
                    fs.Dispose();
                    File.Delete(fileurl);//删除上传至应用服务器的文件
                }

                at.ajaxDataFlag = true;
                at.ajaxresult = httpurl;

            }
            catch (Exception ex)
            {
                at.ajaxDataFlag = false;
                at.ajaxresult = "服务器内部错误,请联系开发人员!";
                ALogOut.debug(ex.ToString());
            }
            return JsonConvert.SerializeObject(at);
        }

2.1.window身份认证
文件上传到文件服务器时,如果应用服务器和文件服务器在同一台服务器,IIS会启用“window身份认证”。

这里会有个比较变态的问题,就是应用站点和文件服务器站点用域名发布后,默认为80端口,这时候上传文件会出现错误403,需要在文件服务器新增一个IP+端口的网站绑定,将文件域名的上传地址替换成IP+端口的地址,就可以解决这个问题。

//AuthFlag:0,window身份认证:在应用服务器和文件服务器在同一台服务器时,IIS会启用window身份认证
if (System.Configuration.ConfigurationManager.AppSettings["PhotoFileHttp"] == null || System.Configuration.ConfigurationManager.AppSettings["PhotoFileIP"] == null)
{
    at.ajaxDataFlag = false;
    at.ajaxresult = "未配置文件服务器域名或者文件服务器IP地址,请联系管理员!";
    return JsonConvert.SerializeObject(at);
}
else
{
    //如果文件服务器和应用服务器发布在同一台服务器上,并且端口相同,需要给文件服务器添加一个不一样的端口,并且将文件上传的地址中的域名替换成该IP+端口的地址
    string PhotoFileHttp = System.Configuration.ConfigurationManager.AppSettings["PhotoFileHttp"].ToString();
    string PhotoFileIP = System.Configuration.ConfigurationManager.AppSettings["PhotoFileIP"].ToString();
    httpurl = httpurl.Replace(PhotoFileHttp, PhotoFileIP);
}
client.Credentials = CredentialCache.DefaultCredentials;//发送身份认证凭证

2.2.匿名身份认证
文件上传到文件服务器时,如果应用服务器和文件服务器在不在同一台服务器,IIS会启用“匿名身份认证”,这里主要需要对IIS进行配置。
IIS配置和常见错误解决办法:

错误401
错误原因
从IIS 7.0开始,不允许匿名写入WebDAV发布目录。具体来说,PUT,MKCOL,PROPPATCH,COPY,MOVE,DELETE和基于WebDAV的GET请求都需要身份验证。
解决方案
1.创建计算机用户,分配管理员权限,设置用于隶属于组;

2.打开IIS选中站点,进入身份验证,右键点击匿名身份验证,选择编辑,同时选择特定用户,输入刚刚添加的用户;
在这里插入图片描述

3.右键点击IIS发布的网站,选择编辑权限,将刚刚添加的用户分配完全控制权限;
在这里插入图片描述

4。点击IIS界面右侧基本设置,点击连接为,并选中特定用户,点击设置输入刚刚创建的用户名和密码;
在这里插入图片描述

5.设置身份认证凭证,这里的用户名、密码需要和IIS基本设置的特定用户的用户名和密码相同。

//AuthFlag:1,匿名身份认证:当应用服务器和文件服务器不在同一台服务器时,IIS会启用匿名身份认证
if (System.Configuration.ConfigurationManager.AppSettings["AuthUser"] == null || System.Configuration.ConfigurationManager.AppSettings["AuthPwd"] == null)
{
    at.ajaxDataFlag = false;
    at.ajaxresult = "未配置匿名身份认证特定用户名或密码,请联系管理员!";
    return JsonConvert.SerializeObject(at);
}
else
{
    AuthUser = System.Configuration.ConfigurationManager.AppSettings["AuthUser"];
    AuthPwd = System.Configuration.ConfigurationManager.AppSettings["AuthPwd"];
}

client.Credentials = new NetworkCredential(AuthUser, AuthPwd);//发送身份认证凭证

错误405
1.选择IIS的WebDAV创作规则,
在这里插入图片描述

2.点击启用WebDAV
在这里插入图片描述

错误403
1.选择IIS的WebDAV创作规则,
在这里插入图片描述

2.选择添加创作规则
在这里插入图片描述

3.按照如图所示操作后,点击确定
在这里插入图片描述

错误409
文件路径不存在;

总结
优点:不会影响其他站点的文件,安全性较高;
缺点:因为需要把文件上传到应用服务器,再上传到文件服务器,相当于上传了两次,如果碰到大文件或多文件上,传效率较低。

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值