服务端接收文件流代码:

        public async Task<HttpResponseMessage> ReceiveFileByStream()
{
var stream = HttpContext.Current.Request.InputStream;
if (stream.Length > )
{
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, , bytes.Length);
//前两个字节代表文件类型,这里以 JPG 类型为例
var bs = bytes[].ToString() + bytes[].ToString();
if (bs.Equals(""))
{
fileType = ".jpg";
}
var path = absolutePath + Guid.NewGuid() + fileType;
await Task.Run(() =>
{
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
{
fs.Write(bytes, , 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:\Users\xxxx\Desktop\woman.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:\Users\xxxx\Desktop\woman.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();
var str = Encoding.UTF8.GetString(bytes, , 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 () { }
});
}

收工!

web api 如何通过接收文件流的方式,接收客户端及前端上传的文件的更多相关文章

  1. java客户端调用ftp上传下载文件

    1:java客户端上传,下载文件. package com.li.utils; import java.io.File; import java.io.FileInputStream; import ...

  2. C# FormData 文件太大报错404 Form表单上传大文件,无法进入后台Action,页面提示404.

    web.config中添加如下节点 <system.webServer> <security>      <requestFiltering >        &l ...

  3. File API 读取上传的文件

    1, 在html 文档中,<input type="file"> 我们可以选择文件进行上传,但这时只能上传一个文件.如果加上multiple 属性,可以上传多个文件,上 ...

  4. 用百度webuploader分片上传大文件

    一般在做文件上传的时候,都是通过客户端把要上传的文件上传到服务器,此时上传的文件都在服务器内存,如果上传的是视频等大文件,那么服务器内存就很紧张,而且一般我们都是用flash或者html5做异步上传, ...

  5. extjs实现简单的多文件上传(不借助任何插件),以及包含处理上传大文件的错误的各种处理办法

    在extjs的学习过程中,有遇到过有关多文件上传的问题,但是网上的大多数都是专门的去实现多文件上传而去做的组件之类的,没有特别简单的方式,于是小白便做了下面的内容,只是通过动态的去添加extjs的自带 ...

  6. ASP.NET 使用 plupload 上传大文件时出现“blob”文件的Bug

    最近在一个ASP.NET 项目中使用了plupload来上传文件,结果几天后客户发邮件说上传的文件不对,说是文件无法打开 在进入系统进行查看后发现上传的文件竟然没有后缀,经过一番测试发现如果文件上传的 ...

  7. 自实现input上传指定文件到服务器

    遇到问题,解决问题,记录问题,成长就是一步一步走出来的. 一.添加 input 标签 我的工作中遇到了,需要上传pdf文件到服务器的需求,而且只能上传pdf文件,accept指定了 pdf 类型. & ...

  8. 用java 代码下载Samba服务器上的文件到本地目录以及上传本地文件到Samba服务器

    引入: 在我们昨天架设好了Samba服务器上并且创建了一个 Samba 账户后,我们就迫不及待的想用JAVA去操作Samba服务器了,我们找到了一个框架叫 jcifs,可以高效的完成我们工作. 实践: ...

  9. QQ上传大文件为什么这么快

    今天和同事在群里讨论“QQ上传大文件/QQ群发送大文件时,可以在极短的时间内完成”是如何做到的. 有时候我们通过QQ上传一个几百M的文件,竟然只用了几秒钟,从带宽上限制可以得出,实际上传文件是不可能的 ...

随机推荐

  1. Spring Boot Actutaur + Telegraf + InFluxDB + Grafana 构建监控平台之应用数据分析

    本节将引入完美的granafa仪表板,在上节的基础上,并提出自己的一些监控数据的总结和看法 你可以有一个类似于这个的Dashboard,会引入监控Zimbra协作 本节环境采用的是centos7系统, ...

  2. LAMP基础

    前言:上一篇博文,说到了URL.http的协议.事务以及私有https的实现.此次 一. 概念: LAMP: a:apache m:mariadb,mysql p:php,perl,python 二. ...

  3. 今天给大家分享用Python matplotlib来写随机漫步的小程序

    先安装两个库: pip install matplotlib pip install numpy 引用库: import matplotlib.pyplot as mp import numpy as ...

  4. Redis 桌面管理器

    使用Redis桌面管理器,可以方便开发人员进行开发测试,对Redis存储内容进行可视化管理. 下载安装:https://redisdesktop.com/download 1. 为了方便测试,打开re ...

  5. Lintcode212 Space Replacement solution 题解

    [题目描述] Write a method to replace all spaces in a string with%20. The string is given in a characters ...

  6. 关于better-scroll中的问题点

    最近在学习vue和better-scroll结合开发音乐APP,看着视频介绍中在制作slidet轮播图的时候,视频中讲解要想实现无缝滚动,则加入snapLoot:true,但是不可以单独引入它,必须将 ...

  7. 软件测试第二周作业 WordCount

    本人github地址:  https://github.com/wenthehandsome23 psp阶段 预估耗时 (分钟) 实际耗时 (分钟) 计划 30 10 估计这个任务需要多少时间 20 ...

  8. 剑指Offer-构建乘积数组

    package Array; import sun.security.util.Length; /** * 构建乘积数组 * 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,... ...

  9. c++ --> union介绍

    union介绍 共用体,也叫联合体,在一个“联合”内可以定义多种不同的数据类型, 一个被说明为该“联合”类型的变量中,允许装入该“联合”所定义的任何一种数据,这些数据共享同一段内存,以达到节省空间的目 ...

  10. Spring Boot 2.0(五):Docker Compose + Spring Boot + Nginx + Mysql 实践

    我知道大家这段时间看了我写关于 docker 相关的几篇文章,不疼不痒的,仍然没有感受 docker 的便利,是的,我也是这样认为的,I know your felling . 前期了解概念什么的确实 ...