在AngularJS中以相同的请求处理上传文件和JSON格式数据
2016-08-24 10:35
681 查看
原文出处:http://shazwazza.com/post/uploading-files-and-json-data-in-the-same-request-with-angular-js/
我决定写一遍快速介绍这方面的文章,因为很多关于这方面的文档或例子都太片面了。通过这篇文章,我们将学会实现用同样的请求处理来上传任意数量的文件和其他任意格式的数据。这个例子我们会上传一些Json格式的数据和文件。
文件上传指令
首先,我们先建立一个的文件上传的Angular指令。
然后,很简单的应用它:
multiple属性说明这个例子支持用户可以选择多个文件进行上传。
在上面指令中,我们要确定建立一个新的作用域。然后,去监听 input file元素的change事件。当监测到文件对象变化时,将会触发作用域中的事件,以及其父作用域中的事件(向上层)。
创建控制器
接下来,我们要创建一个控制器:
1.创建一个绑定它的模型
2.创建一个文件集合
3.创建一个绑定事件的处理程序,以便我们将文件放入文件集合中。
4.创建一个方法,来上传文件到服务器上。
备注:为了更快捷,我将所有的方法都放到一个控制器中。在大多数情况下,你需要将它们放到不同的处理数据的工厂方法中。
控制器放在这里,这个标注用起来像下面这样(将会显示所有选择的文件)
在控制器中,如下面的代码含有一些很重要的关于如何获得上传到服务器端数据的备注,协议头中Content-Type一定要被设置,看起来很诡异吧。
//译者备注:这段很重要,重点之关键
function
Ctrl($scope, $http) {
//a
simple model to bind to and send to the server
$scope.model = {
name:
"",
comments:
""
};
//an
array of files selected
$scope.files = [];
//listen
for the file selected event
$scope.$on("fileSelected",
function
(event,
args) {
$scope.$apply(function
() {
//add
the file object to the scope's files collection
$scope.files.push(args.file);
});
});
//the
save method
$scope.save =
function()
{
$http({
method:
'POST',
url:
"/Api/PostStuff",
//IMPORTANT!!!
You might think this should be set to 'multipart/form-data'
//
but this is not true because when we are sending up files the request
//
needs to include a 'boundary' parameter which identifies the boundary
//
name between parts in this multi-part request and setting the Content-type
//
manually will not set this boundary parameter. For whatever reason,
//
setting the Content-type to 'false' will force the request to automatically
//
populate the headers properly including the boundary parameter.
headers: {
'Content-Type':
false
},
//This
method will allow us to change how the data is sent up to the server
//
for which we'll need to encapsulate the model data in 'FormData'
transformRequest:
function
(data) {
var
formData = new
FormData();
//need
to convert our json object to a string version of json otherwise
//
the browser will do a 'toString()' on the object which will result
//
in the value '[Object object]' on the server.
formData.append("model",
angular.toJson(data.model));
//now
add all of the assigned files
for
(var
i = 0; i < data.files; i++) {
//add
each file to the form data and iteratively name them
formData.append("file"
+ i, data.files[i]);
}
return
formData;
},
//Create
an object that contains the model and files which will be transformed
//
in the above transformRequest method
data: { model: $scope.model, files: $scope.files }
}).
success(function
(data, status, headers, config) {
alert("success!");
}).
error(function
(data, status, headers, config) {
alert("failed!");
});
};
};
处理服务器端的数据
这个例子展示了用Asp.net Web Api来处理服务器端的数据。我敢肯定,在其他服务器点平台也是相当容易的。
public async Task<HttpResponseMessage> PostStuff()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var root = HttpContext.Current.Server.MapPath("~/App_Data/Temp/FileUploads");
Directory.CreateDirectory(root);
var provider = new MultipartFormDataStreamProvider(root);
var result = await Request.Content.ReadAsMultipartAsync(provider);
if (result.FormData["model"] == null)
{
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
var model = result.FormData["model"];
//TODO: Do something with the json model which is currently a string
//get the files
foreach (var file in result.FileData)
{
//TODO: Do something with each uploaded file
}
return Request.CreateResponse(HttpStatusCode.OK, "success!");
}
我决定写一遍快速介绍这方面的文章,因为很多关于这方面的文档或例子都太片面了。通过这篇文章,我们将学会实现用同样的请求处理来上传任意数量的文件和其他任意格式的数据。这个例子我们会上传一些Json格式的数据和文件。
文件上传指令
首先,我们先建立一个的文件上传的Angular指令。
app.directive('fileUpload', function () { return { scope: true, //create a new scope link: function (scope, el, attrs) { el.bind('change', function (event) { var files = event.target.files; //iterate files since 'multiple' may be specified on the element for (var i = 0;i<files.length;i++) { //emit event upward scope.$emit("fileSelected", { file: files[i] }); } }); } }; });
然后,很简单的应用它:
<input type="file" file-upload multiple/>
multiple属性说明这个例子支持用户可以选择多个文件进行上传。
在上面指令中,我们要确定建立一个新的作用域。然后,去监听 input file元素的change事件。当监测到文件对象变化时,将会触发作用域中的事件,以及其父作用域中的事件(向上层)。
创建控制器
接下来,我们要创建一个控制器:
1.创建一个绑定它的模型
2.创建一个文件集合
3.创建一个绑定事件的处理程序,以便我们将文件放入文件集合中。
4.创建一个方法,来上传文件到服务器上。
备注:为了更快捷,我将所有的方法都放到一个控制器中。在大多数情况下,你需要将它们放到不同的处理数据的工厂方法中。
控制器放在这里,这个标注用起来像下面这样(将会显示所有选择的文件)
<div ng-controller="Ctrl"> <input type="file" file-upload multiple/> <ul> <li ng-repeat="file in files">{{file.name}}</li> </ul> </div>
在控制器中,如下面的代码含有一些很重要的关于如何获得上传到服务器端数据的备注,协议头中Content-Type一定要被设置,看起来很诡异吧。
//译者备注:这段很重要,重点之关键
function
Ctrl($scope, $http) {
//a
simple model to bind to and send to the server
$scope.model = {
name:
"",
comments:
""
};
//an
array of files selected
$scope.files = [];
//listen
for the file selected event
$scope.$on("fileSelected",
function
(event,
args) {
$scope.$apply(function
() {
//add
the file object to the scope's files collection
$scope.files.push(args.file);
});
});
//the
save method
$scope.save =
function()
{
$http({
method:
'POST',
url:
"/Api/PostStuff",
//IMPORTANT!!!
You might think this should be set to 'multipart/form-data'
//
but this is not true because when we are sending up files the request
//
needs to include a 'boundary' parameter which identifies the boundary
//
name between parts in this multi-part request and setting the Content-type
//
manually will not set this boundary parameter. For whatever reason,
//
setting the Content-type to 'false' will force the request to automatically
//
populate the headers properly including the boundary parameter.
headers: {
'Content-Type':
false
},
//This
method will allow us to change how the data is sent up to the server
//
for which we'll need to encapsulate the model data in 'FormData'
transformRequest:
function
(data) {
var
formData = new
FormData();
//need
to convert our json object to a string version of json otherwise
//
the browser will do a 'toString()' on the object which will result
//
in the value '[Object object]' on the server.
formData.append("model",
angular.toJson(data.model));
//now
add all of the assigned files
for
(var
i = 0; i < data.files; i++) {
//add
each file to the form data and iteratively name them
formData.append("file"
+ i, data.files[i]);
}
return
formData;
},
//Create
an object that contains the model and files which will be transformed
//
in the above transformRequest method
data: { model: $scope.model, files: $scope.files }
}).
success(function
(data, status, headers, config) {
alert("success!");
}).
error(function
(data, status, headers, config) {
alert("failed!");
});
};
};
处理服务器端的数据
这个例子展示了用Asp.net Web Api来处理服务器端的数据。我敢肯定,在其他服务器点平台也是相当容易的。
public async Task<HttpResponseMessage> PostStuff()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var root = HttpContext.Current.Server.MapPath("~/App_Data/Temp/FileUploads");
Directory.CreateDirectory(root);
var provider = new MultipartFormDataStreamProvider(root);
var result = await Request.Content.ReadAsMultipartAsync(provider);
if (result.FormData["model"] == null)
{
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
var model = result.FormData["model"];
//TODO: Do something with the json model which is currently a string
//get the files
foreach (var file in result.FileData)
{
//TODO: Do something with each uploaded file
}
return Request.CreateResponse(HttpStatusCode.OK, "success!");
}
相关文章推荐
- RxJava + Retrofit+okhttp 封装,包含对相同格式请求数据、相同格式返回数据处理,显示 Material Design 加载 dialog,文件上传下载进度展示、全局异常捕捉。
- Struts2-day03 文件上传, json格式 , 处理ajax请求 , 注解开发
- C# winform端 通过HttpWebRequest进行post和get请求,数据格式为json,后台java端接收,其中有关传输特殊字符(\t,\r,',\n,n)等处理
- json格式数据的请求处理
- Python处理json格式的数据文件(一些坑、一些疑惑)
- 使用jquery uploadfy插件上传文件返回json格式的处理办法
- 处理文件上传后返回json数据在IE出现文件下载问题
- ios网络学习------5 json格式数据的请求处理
- struts1 采用json格式发送异步请求,并且获取action处理后的json数据
- struts1 采用json格式发送异步请求,并且获取action处理后的json数据
- PHP 使用curl库来发送GET,POST请求,处理json格式数据
- php学习笔记(三十)ajax请求和接收参数的实现方式(包括json数据格式的简单处理)
- ie8下使用jquery-file-upload上传文件后返回json格式数据提示下载
- ajax处理请求,以JSON数据格式返回,(json时间日期返回时对象---》日期格式)
- ios网络学习------6 json格式数据的请求处理
- laravel之获取请求数据、cookie、文件上传处理
- ExtJS fileupload组件上传文件后从服务端解析JSON格式数据
- ASP.NET MVC上传文件成功返回Json格式数据弹出下载框解决方案
- struts1 采用json格式发送异步请求,并且获取action处理后的json数据 .
- struts2 + ajax(由前台的form提交数据到后台,再根据form所调用返回获取的后台json格式的数据返回到前端,然后前端用jquery对json数据进行解析)==》》涉及文件上传的部分