服务端接收文件流代码:

        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. js常见算法(一)

    1.每个单词手字母大写 var capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase( ...

  2. 解决Win10下_findnext()异常

    在win10中,使用文件遍历函数_findnext会报0xC0000005错误 ,发生访问冲突错误 错误定位到ntdll.dll 原因: _findnext()第一个参数"路径句柄" ...

  3. windows中安装redis

    Redis是有名的NoSql数据库,一般Linux都会默认支持.但在Windows环境中, Windows的Redis安装包需要到以下GitHub链接找到.链接:https://github.com/ ...

  4. LintCode主元素

    主元素1: 这道题是编程之美上的一道原题,如果题目未对时间复杂度有严格要求的话可以先排序,再取中位数. 本题中要求算法达到时间复杂度为O(n),空间复杂度为O(1),算法如下: public int ...

  5. 关于Cesium中的常用坐标系及说明

    Cesium是一个基于JavaScript的开源框架,可用于在浏览器中绘制3D的地球,并在其上绘制地图(支持多种格式的瓦片服务),该框架不需要任何插件支持,但是浏览器必须支持WebGL. Cesium ...

  6. conda下载速度慢——添加源

    清华提供的anaconda镜像,使用以后真的很快!尤其在学校龟速的网络环境里提速非常明显. https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/ TU ...

  7. Java 英文面试题

    1. Q: What is HashMap and Map?A: Map is Interface and Hashmap is class that implements that. 2. Q: D ...

  8. vue技术解析二之组件通信

    --------------------------动画效果----------------------------------- <transition name="router-f ...

  9. docker部署PMA(LNMP架构)

    上篇文章中已经部署好php环境,测试也已经OK centos 7 docker 启动了一个web服务 但是启动时 报 WARNING: IPv4 forwarding is disabled. Net ...

  10. 网络通信 --> 消息队列

    消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法.可以通过发送消息来避免命名管道的同步和阻塞问题.但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制. Linux用宏M ...