Javascript 使用angular将文件复制到服务器
我不敢相信这会如此困难。如果使用nodejs和标准html,我可以通过以下方式传输文件: index.html:Javascript 使用angular将文件复制到服务器,javascript,angularjs,node.js,Javascript,Angularjs,Node.js,我不敢相信这会如此困难。如果使用nodejs和标准html,我可以通过以下方式传输文件: index.html: <form id = "uploadForm" enctype = "multipart/form-data" action = "/api/photo" method = "post" > <input type="file" name="userPhoto" /> <input typ
<form id = "uploadForm"
enctype = "multipart/form-data"
action = "/api/photo"
method = "post"
>
<input type="file" name="userPhoto" />
<input type="text" placeholder="keywords" name="keywords" />
<input type="submit" value="Upload Image" name="submit">
</form>
</<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.0-rc.1/angular.min.js"></script>
</head>
<body ng-app="formExample">
<div ng-controller="ExampleController">
<form ng-submit="examplePost()" role="form" >
<input type="file" bind-file="" ng-model="file" />
<input type="text" ng-model="keywords" placeholder="keywords"/>
<input type="submit" ng-onclick="submit" value="Upload Image" >
</form>
</div>
<script>
angular.module('formExample', [])
.controller('ExampleController', ['$scope', '$http', function($scope,$http) {
$scope.master = {};
$scope.examplePost = function() {
$http({
method: 'POST',
url: '/upload-file',
headers: {
'Content-Type': 'multipart/form-data'
},
data: {
upload: $scope.file
},
transformRequest: function (data, headersGetter) {
var formData = new FormData();
angular.forEach(data, function (value, key) {
formData.append(key, value);
});
return formData;
}
})
.success(function (data) {
})
.error(function (data, status) {
});
};
}])
.directive('bindFile', [function () {
return {
require: "ngModel",
restrict: 'A',
link: function ($scope, el, attrs, ngModel) {
el.bind('change', function (event) {
ngModel.$setViewValue(event.target.files[0]);
$scope.$apply();
});
$scope.$watch(function () {
return ngModel.$viewValue;
}, function (value) {
if (!value) {
el.val("");
}
});
}
};
}]);
</script>
</body>
</html>
这样,我加载的任何图片都会复制到uploads文件夹中。现在,出于不同的原因,我想使用angular。事实证明,我需要一个指令。为什么,我不明白(但那是真的)。因为我使用的是multer,所以我需要数据的类型为“multipart/formdata”。这是我的index.html:
<form id = "uploadForm"
enctype = "multipart/form-data"
action = "/api/photo"
method = "post"
>
<input type="file" name="userPhoto" />
<input type="text" placeholder="keywords" name="keywords" />
<input type="submit" value="Upload Image" name="submit">
</form>
</<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.0-rc.1/angular.min.js"></script>
</head>
<body ng-app="formExample">
<div ng-controller="ExampleController">
<form ng-submit="examplePost()" role="form" >
<input type="file" bind-file="" ng-model="file" />
<input type="text" ng-model="keywords" placeholder="keywords"/>
<input type="submit" ng-onclick="submit" value="Upload Image" >
</form>
</div>
<script>
angular.module('formExample', [])
.controller('ExampleController', ['$scope', '$http', function($scope,$http) {
$scope.master = {};
$scope.examplePost = function() {
$http({
method: 'POST',
url: '/upload-file',
headers: {
'Content-Type': 'multipart/form-data'
},
data: {
upload: $scope.file
},
transformRequest: function (data, headersGetter) {
var formData = new FormData();
angular.forEach(data, function (value, key) {
formData.append(key, value);
});
return formData;
}
})
.success(function (data) {
})
.error(function (data, status) {
});
};
}])
.directive('bindFile', [function () {
return {
require: "ngModel",
restrict: 'A',
link: function ($scope, el, attrs, ngModel) {
el.bind('change', function (event) {
ngModel.$setViewValue(event.target.files[0]);
$scope.$apply();
});
$scope.$watch(function () {
return ngModel.$viewValue;
}, function (value) {
if (!value) {
el.val("");
}
});
}
};
}]);
</script>
</body>
</html>
关于什么是“边界”,维基百科对此做了大量解释:
MIME多部分消息在“内容类型:”中包含边界:
收割台;此边界不得出现在任何零件中,因此
放置在零件之间,以及零件主体的开始和结束处
电文如下:
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=frontier
This is a message with multiple parts in MIME format.
--frontier
Content-Type: text/plain
This is the body of the message.
--frontier
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg
Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg==
--frontier--
在这个答案的基础上:考虑到OP的代码中,内容类型
标题被删除的方式,声明的边界很可能也被删除(并且边界也不会在标题
对象中声明)。OP应该查看发送的HTTP头以查看发生了什么。(使用devtools应该很容易)我删除了内容类型声明。同样的问题。@cauchy:然后查看HTTP头(例如,在Chrome developer tools中打开“网络”选项卡,然后重做流程-HTTP请求和响应应该出现,并且您应该能够看到发送的头值是什么样子)内容类型在那里(正如预期的那样是多部分/表单数据),但正如服务器的响应所说,没有边界。在这个调用中,从@Dmitry发布的信息来看,边界是这样的:---WebKitFormBoundary8NfqfKxFBAK7jMmJ。所以我想我在调用的头部缺少边界定义。