• web api 如何通过接收文件流的方式,接收客户端及前端上传的文件


    服务端接收文件流代码:

            public async Task<HttpResponseMessage> ReceiveFileByStream()
            {
                var stream = HttpContext.Current.Request.InputStream;
                if (stream.Length > 0)
                {
                    var absolutePath = HttpContext.Current.Request.MapPath("/img/");
                    if (!Directory.Exists(absolutePath))
                    {
                        Directory.CreateDirectory(absolutePath);
                    }
                    var fileType = "";
                    var bytes = new byte[stream.Length];
                    stream.Read(bytes, 0, bytes.Length);
                    //前两个字节代表文件类型,这里以 JPG 类型为例
                    var bs = bytes[0].ToString() + bytes[1].ToString();
                    if (bs.Equals("255216"))
                    {
                        fileType = ".jpg";
                    }
                    var path = absolutePath + Guid.NewGuid() + fileType;
                    await Task.Run(() =>
                    {
                        using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
                        {
                            fs.Write(bytes, 0, bytes.Length);
                        }
                    });
                    return Request.CreateResponse(HttpStatusCode.OK, "上传成功!");
                }
                else
                {
                    return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "没有文件耶,哥们!");
                }
            }

    客户端上传文件流代码:

    HttpClient

            static string TestHttpClientUpload()
            {
                var resultStr = string.Empty;
                HttpClient client = new HttpClient();
                client.BaseAddress = new Uri("http://192.168.20.15:57895");
                string apiUrl = "api/upload/ReceiveFileByStream";
    string path = @"C:UsersxxxxDesktopwoman.jpg"; FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
    HttpContent content
    = new StreamContent(fs); var result = client.PostAsync(apiUrl, content).Result; fs.Dispose(); resultStr = result.Content.ReadAsStringAsync().Result; return resultStr;//上传成功 }

    HttpWebRequest 

            static string TestHttpWebRequestUpload()
            {
                var resultStr = string.Empty;
                string url = "http://192.168.20.15:57895/api/upload/ReceiveFileByStream";
                HttpWebRequest request = WebRequest.CreateHttp(url);
                request.Method = "post";
    
                string path = @"C:UsersxxxxDesktopwoman.jpg";
                FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
                var requestStream = request.GetRequestStream();
                fs.CopyTo(requestStream);
                fs.Dispose();
                requestStream.Dispose();
    
                var result = request.GetResponseAsync().Result;
                var responseStream = result.GetResponseStream();
                using (StreamReader sm = new StreamReader(responseStream))
                {
                    resultStr = sm.ReadToEnd();
                }
                return resultStr;//上传成功
            }

    前端上传文件:

        <div>
            <span>Form表单上传单个文件</span><br />
            <form id="myForm1" enctype="multipart/form-data" method="post" action="http://192.168.20.15:57895/api/upload/ReceiveFileByStream">
                <input type="file" name="myFile" />
                <input type="submit" value="submit提交" />
            </form>
        </div>

    上面三种方式,客户端没有问题,但是前端这样上传是有问题的,因为在文件流开头还有其他东西:

    用一段代码测试:

                    //这里的 255 是 255216 里面的 255, 从 255 所在的位置开始才是文件的字节数据
                    var index = bytes.ToList().IndexOf(255);
                    var str = Encoding.UTF8.GetString(bytes, 0, index);
                    Trace.WriteLine(str);

    这就是HTTP请求自带的,打开浏览器,F12,可以看到:

    那么,如何成功的躲避这一段字节呢?

    答案是 : 利用 Ajax 提交表单

        <div>
            <form id="myForm4">
                <input type="file" id="myFile" />
                <input type="button" value="AJAX提交图片" onclick="uploadFile()" />
            </form>
        </div>
            function uploadFile() {
                var url = "http://192.168.20.15:57895/api/upload/ReceiveFileByStream";
                var data = $("#myFile")[0].files[0];
                $.ajax({
                    url: url,
                    data: data,
                    type: "post",
                    processData: false,//表示提交的时候不会序列化 data,而是直接使用 data,默认为 true
                    contentType: false,//表示不要去设置Content-Type请求头
                    cache: false,//设置为 false 将不会从浏览器缓存中加载请求信息。
                    success: function () { }
                });
            }

    但是,这样提交在跨域的时候,会有一次 OPTIONS 请求

    下面那次请求才是 POST 请求,至于为什么会有一次 OPTIONS 请求,大家可以自行百度,这里就不说了.

    那么如何成功的避免这次 OPTIONS 请求呢?

    答案就是 : Ajax 请求的时候, 不设置  contentType 属性!

            function uploadFile() {
                var url = "http://192.168.20.15:57895/api/upload/ReceiveFileByStream";
                var data = $("#myFile")[0].files[0];
                $.ajax({
                    url: url,
                    data: data,
                    type: "post",
                    processData: false,//表示提交的时候不会序列化 data,而是直接使用 data,默认为 true
                    cache: false,//设置为 false 将不会从浏览器缓存中加载请求信息。
                    success: function () { }
                });
            }

    收工!

  • 相关阅读:
    创建user keywords
    robotframework中list和dict variables
    安装sshlibrary库报错:Could not find a version that satisfies the requirement
    【转】用U盘制作启动盘后空间变小的恢复方法
    docker "exec format error"
    window cmd 设置IP,关闭防火墙,开启远程桌面
    Linux iptables
    python logging 模块
    docker 命令
    python xmlrpc入门
  • 原文地址:https://www.cnblogs.com/refuge/p/8534847.html
Copyright © 2020-2023  润新知