关于上一篇 :
原生JS实现AJAX及其原理
转载的文章后 继续瞎搞 研究了下跨域上传文件
利用JS实现ajax 来跨域上传文件(没有使用 jsonp 因为它只能是GET 访问)
简单说一下过程:
1 .我先建立了一个webapi的文件服务器,并在里面写了这样的简单方法
[HttpPost]
public string UploadFile()
{
HttpContext.Current.Response.ContentType = "application/json;charset=utf-8";
//获取回调函数名
var request = HttpContext.Current.Request;
var result = 200;
//获取文件
HttpPostedFile file = request.Files["File"];
if (file == null)
result = 404;
string fileName = file.FileName;
string extension = Path.GetExtension(fileName);
int fileSize = file.ContentLength;
//大小1M
if (fileSize > 10240)
result = 500;
if (result == 200)
{
//注意这里我是的地址,你可以更改
string dirPath = Path.Combine("d:/documents/visual studio 2012/Projects/HttpFileServer/HttpFileServer/Images/");
string newFileName = string.Format("KY_{0}{1}", DateTime.Now.ToString("yyMMddHHmmssfffffff"), fileName + extension);
if (!Directory.Exists(dirPath))
Directory.CreateDirectory(dirPath);
string sourcePath = dirPath + newFileName;
file.SaveAs(sourcePath);
}
return result.ToString();
}
2. 在建立一个常规的MVC4 项目
前台:
<div>
<input type="text" id="ajaxcode" />
<button id="butcode" οnclick="butcodeclick()">获取code</button>
</div>
<br />
<br />
<form enctype="multipart/form-data" id="fromUpload">
<input name="file" type="file" id="fileId" />
<input type="button" οnclick="Uploadclick()" value="Upload" />
<input type="button" id="JqueryUpload" value="JqueryUpload" />
</form>
<script src="~/Assets/jquery-3.2.1.min.js"></script>
<script>
$(function () {
$("#JqueryUpload").click(function () {
//var file = $("#fromUpload input").files[0];
var formData = new FormData();
formData.append('file', $('#fileId')[0].files[0]);
$.ajax({
type: "POST", //必须用post
url: "/Home/uploadfile",
data: formData,
dataType: "json",
contentType: false, //必须
processData: false,
async: false,
success: function (ret) {
$("#ajaxcode").val(ret);
},
});
});
})
function butcodeclick() {
ajax({
url: "/Home/ajaxreturn", //请求地址
type: "Get", //请求方式
data: { name: "WeideMo", age: 26 }, //请求参数
dataType: "json",
success: function (response, xml) {
// 此处放成功后执行的代码
console.log(321);
document.getElementById("ajaxcode").value = response;
},
fail: function (status) {
// 此处放失败后执行的代码
console.log(123);
}
});
}
function Uploadclick() {
var files = document.getElementById("fileId").files[0]
var formData = new FormData();
formData.append('file', files);
var code = document.getElementById("ajaxcode");
ajax({
url: "/home/uploadfile", //请求地址
type: "post", //请求方式
data: formData, //请求参数
datatype: "json",
cache: false,
contenttype: false,
processdata: false,
success: function (response, xml) {
// 此处放成功后执行的代码
code.value = response;
},
fail: function (response, xml) {
// 此处放失败后执行的代码
code.value = response;
}
});
}
function ajax(options) {
options = options || {};
options.type = (options.type || "GET").toUpperCase();
options.dataType = options.dataType || "json";
//var params = formatParams(options.data);
var params = options.data;
//创建 - 非IE6 - 第一步
if (window.XMLHttpRequest) {
var xhr = new XMLHttpRequest();
} else {
//IE6及其以下版本浏览器
var xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
//接收 - 第三步
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
var status = xhr.status;
//此处不判断304,因为增加随机数后,不命中缓存
if (status >= 200 && status < 300) {
options.success && options.success(xhr.responseText, xhr.responseXML);
} else {
options.fail && options.fail(status);
}
}
}
//连接 和 发送 - 第二步
if (options.type == "GET") {
xhr.open("GET", options.url + "?" + params, true);
xhr.send(null);
} else if (options.type == "POST") {
xhr.open("POST", options.url, true);
//设置表单提交时的内容类型
//xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.send(params);
}
}
//格式化参数
function formatParams(data) {
console.log(data);
var arr = [];
for (var name in data) {
arr.push(encodeURIComponent(name) + "=" + encodeURIComponent(data[name]));
}
arr.push(("v=" + Math.random()).replace(".", ""));
console.log(arr);
return arr.join("&");
}
</script>
后台:
//上传资源路径
string URL = "http://127.0.0.1:32111/api/values/UploadFile";
public ActionResult Index()
{
return View();
}
[HttpGet]
public ActionResult ajaxreturn()
{
return Json("good Welcome to you", JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult UploadFile()
{
//客户端文件数据
HttpPostedFileBase files = Request.Files["file"] ?? null;
if (files != null || files.ContentLength <= 0)
{
string fileFullName = @"c:\" + files.FileName, responseText = "";
byte[] postData = StreamToBytes(files.InputStream);
//上传图片 模拟from表的提交当方式
var httpRequestClient = new HttpRequestClient();
//向自定义的from表的中添加数据
httpRequestClient.SetFieldValue("File", Path.GetFileName(fileFullName), "application/octet-stream", postData);
//向服务端提交数据 并获得返回值
httpRequestClient.Upload(URL, out responseText);
//反序列化
var b = JsonConvert.DeserializeAnonymousType(responseText, "");
//返回自定义状态
switch (b)
{
case "200":
return Json("上传成功!");
case "404":
return Json("文件不在了");
//case "-2":
// return Json("文件格式不正确");
case "500":
return Json("文件太大了");
default:
return Json("对不起,网络异常!");
}
}
return Json("头像上传失败,请稍后再试!");
}
/// <summary>
/// Stream 将它转换为 byte
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public byte[] StreamToBytes(Stream stream)
{
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
// 设置当前流的位置为流的开始
stream.Seek(0, SeekOrigin.Begin);
stream.Close();
stream.Dispose();
return bytes;
}
一些帮助类:(就不贴出来了)
HttpRequestClient (位置在 AjaxOrCross-origin 客户端项目的 Models中)
我把Dome也提供 Js原生ajax与跨域(代理)上传文件