服务端接收文件流代码:
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 () { }
});
}
收工!