我在Debian上使用 PHP 5.6.24 上的 AngularJS v1.6.1, Apache 2.4.10 和我&#39 ; m尝试使用$http
POST服务将文件上传到我的服务器。
在我的php.ini
上,最大文件大小设置为8Mo,最大邮件大小,上传文件打开,内存大小限制设置为128Mo。
形式:
<input type="file" accept="application/pdf" id="uploadOT" max-files="1" ng-model="uploadOT" name="uploadOT" valid-file required ng-class="{'md-input-invalid':uploadForm.uploadOT.$error.validFile}" />
Angular指令:(当输入内容发生变化时,获取FileReader对象并发送文件)
myModule.directive('validFile', function() {
return {
require: 'ngModel',
link: function(scope, elt, attrs, ctrl) {
ctrl.$setValidity('validFile', elt.val() !== '');
elt.bind('change', function() {
var file = document.getElementById('uploadOT').files;
var reader = new FileReader();
reader.onload = function(e) {
scope.sendFile(reader, scope.id);
};
scope.showUploadProgress = true;
scope.filename = file[0].name;
reader.readAsBinaryString(file[0]);
ctrl.$setValidity('validFile', elt.val() !== '');
scope.$apply(function() {
ctrl.$setViewValue(elt.val());
ctrl.$render();
});
});
}
};
});
内部控制器:
$scope.sendFile = function(reader, id) {
var fd = new FormData();
fd.append('id', id);
fd.append('file', reader.result);
fd.append('MAX_FILE_SIZE', 8 * 1024 * 1024);
$http.post('api/upload.php', fd, {
headers: {'Content-Type' : undefined },
transformRequest: angular.identity
}).then(function() {
alert('upload success');
}, function() {
$scope.showUploadError = true;
$scope.showUploadProgress = false;
$scope.postError = 'Une erreur inconnue est survenue !';
});
};
在服务器端(文件api/upload.php
),我使用$_POST
打印变量$_FILES
和print_r()
。
为什么$_FILES
始终为空,我的文件数据位于$_POST['file']
?
我可以使用php函数 $_POST['file']
从file_put_contents()
数据创建文件,但我无法通过 $_FILES
。它真的很重要(安全问题)吗?
如果我将我的POST Content-Type
更改为multipart/form-data
,则会发生同样的事情。
答案 0 :(得分:0)
我认为这是因为你忘了指定表单元素的编码类型。
enctype="multipart/form-data"
因此,通过默认 - 浏览器会假设表单编码类型为&#34; application / x-www-form-urlencoded &#34;以这种方式不支持文件。您仍然可以使用stock编码方法安全地发送文件二进制数据,但这可能是性能和功能决定您选择的因素。我建议运行一些测试来确认哪个是最快的。在某些情况下,差异可以忽略不计,并且可能是为了保持一致。
答案 1 :(得分:0)
跳过FileReader API并直接使用file
对象:
<input type=file files-input ng-model="files" ng-change="upload()" />
filesInput
指令
angular.module("myApp").directive("filesInput", function() {
return {
require: 'ngModel',
link: function linkFn (scope, elem, attrs, ngModel) {
elem.on("change", function (e) {
ngModel.$setViewValue(elem[0].files, "change");
});
},
};
});
upload()
功能
vm.upload = function() {
//var formData = new $window.FormData();
//formData.append("file-0", vm.files[0]);
var config = { headers: { "Content-Type": undefined } };
$http.post(url, vm.files[0], config)
.then(function(response) {
vm.result = "SUCCESS";
}).catch(function(response) {
vm.result = "ERROR "+response.status;
});
};
XHR API send()方法可以发布file
对象或FormData
对象。发送file
对象更有效率,因为XHR API使用base64 encoding用于具有33%开销的FormData
对象。
答案 2 :(得分:0)
为了使其有效,我必须做这些修改:
<强>指令:强>
myModule.directive('validFile', function() {
return {
require: 'ngModel',
link: function(scope, elt, attrs, ctrl) {
ctrl.$setValidity('validFile', elt.val() !== '');
elt.bind('change', function() {
var file = document.getElementById('uploadOT').files;
var reader = new FileReader();
reader.onload = function(e) {
scope.sendFile(file[0], scope.OT); ////CHANGE HERE
};
scope.showUploadProgress = true;
scope.filename = file[0].name;
reader.readAsArrayBuffer(file[0]); ////CHANGE HERE
ctrl.$setValidity('validFile', elt.val() !== '');
scope.$apply(function() {
ctrl.$setViewValue(elt.val());
ctrl.$render();
});
});
}
};
});
内部控制器
$scope.sendFile = function(file, id) {
var fd = new FormData();
fd.append('id', id);
fd.append('file', file);
fd.append('MAX_FILE_SIZE', 8 * 1024 * 1024);
$http({
method: 'POST',
url: 'upload.php',
data: fd,
headers: {'Content-Type': undefined, 'Process-Data': false},
transformRequest: angular.identity
}).then( function() {
console.log('success');
}, function() {
console.log('failure');
});
};