php ajax 文件上传失败 - 部分文件上传错误
php ajax file upload not working - partial file upload error
我已经使用 html、ajax 和 php 编写了用于上传文件以及其他表单输入的代码。我正在使用 ajax 提交表单。一切都在一台服务器上工作,但是当我将代码移动到新服务器时,我不断收到部分文件上传错误。
示例代码如下
HTML:
<form id="gal-form" class="form-gallery" enctype="multipart/form-data">
<input type="hidden" id="gal_id" name="id" value="">
<div class="up-types">
<div class="input-group mb-3 display-none check-links">
<span class="input-group-text">Links to</span>
<input type="text" value="ebooks" disabled="">
<input type="text" name="links[]" class="form-control" data-type="ebooks" id="links_to_3" value="">
</div>
<div class="input-group mb-3 display-none check-links">
<span class="input-group-text">Links to</span>
<input type="text" value="handbooks" disabled="">
<input type="text" name="links[]" class="form-control" data-type="handbooks" id="links_to_4" value="">
</div>
<div class="input-group mb-3 display-none check-links">
<span class="input-group-text">Links to</span>
<input type="text" value="manuals" disabled="">
<input type="text" name="links[]" class="form-control" data-type="manuals" id="links_to_5" value="">
</div>
</div>
<div class="form-group">
<label for="gal_title">Title</label>
<input type="text" class="form-control" id="gal_title" name="title" placeholder="Add a title here..">
</div>
<div class="form-group">
<label for="gal_title">Category</label>
<input id="gallery_tags" class="form-control" name="tags[]" type="text" value="" placeholder="Add a category here..">
</div>
<div class="form-group">
<label>File upload <span class="text-danger">*Only PDF, MP4, WEBM, OGG, JPG, JPEG, & PNG files are allowed. Please try to upload images/videos of a specific aspect ratio</span></label>
<input type="file" name="gal" id="gal-file" class="file-upload-default">
<div class="input-group col-xs-12">
<input type="text" class="form-control file-upload-info" disabled="" placeholder="Upload File">
<span class="input-group-append">
<button class="file-upload-browse btn btn-primary" type="button">Browse</button>
</span>
</div>
</div>
<div class="form-group">
<label for="event_text">Description</label>
<textarea class="form-control" id="media_desc" name="desc" rows="4" aria-hidden="true"></textarea>
</div>
<button type="submit" id="gal-button" class="btn btn-primary mr-2">Submit</button>
</form>
我要设置一些来自 javascript 的参数,所以,
$("#gal-form").on('submit', function(e) {
e.preventDefault();
var desc = "Some description here";
if ($('#gal_title').val() == '') {
$('#display-msg').html('<span style="color:red">Please enter title name...</span>');
return false;
} else if ($('#gal-file').get(0).files.length === 0 && !desc) {
$('#display-msg').html('<span style="color:red">Please enter a description or choose a file to upload...</span>');
return false;
}
var formData = new FormData(this);
var values = $("input[name='links[]']:enabled").map(function() {
let id = this.id.split("_").pop();
let link = $(this).data("type");
if (this.value) {
link += "/" + this.value;
}
return {
id: id,
link: link
};
}).get();
formData.append('links_to', JSON.stringify(values));
formData.set('desc',desc);
$.ajax({
type: 'POST',
url: 'url',
data: formData,
dataType: 'json',
contentType: false,
cache: false,
processData: false,
success: function(obj) {
if (obj.success) {
window.location.reload();
} else {
alertItem(obj.error);
}
},
error: function(request, status, error) {
alertItem(request.responseText);
}
});
});
并且在PHP,
$uploadStatus = 1;
$data = array();
if(!empty($_FILES["gal"]["name"])){
$file_name = pathinfo(basename($_FILES["gal"]["name"]),PATHINFO_FILENAME);
$fileType = pathinfo(basename($_FILES["gal"]["name"]), PATHINFO_EXTENSION);
$fileName = $this->generateSlug($file_name).'_'.time().'.'.$fileType;
$targetFilePath = $fileName;
$allowTypes = array('pdf', 'mp4', 'webm', 'ogg', 'jpg', 'png', 'jpeg');
if(in_array(strtolower($fileType), $allowTypes)){
if(move_uploaded_file($_FILES["gal"]["tmp_name"], $targetFilePath)){
$data['file'] = $fileName;
}else{
$uploadStatus = 0;
return array('error'=>$_FILES["error"]));
}
}else{
$uploadStatus = 0;
return array('error'=>'Sorry, only PDF, MP4, WEBM, OGG, JPG, JPEG, & PNG files are allowed to upload.');
}
}
if($uploadStatus == 1){
//Add to database
}
如果直接从 PHP 提交表单,上传将有效。我查看并比较了 apache 和 php 配置以检查是否有任何遗漏。下面是apache和php的服务器配置。在 Server1 和 Server2 中都可以上传。
服务器 1:
Apache/2.4.6 (RHEL 7.9)
PHP 7.3.29
服务器 2:
Apache/2.4.37 (RHEL 8.4)
PHP 7.4.19
服务器 3(新服务器):
Apache/2.4.46 (RHEL 7.9)
PHP 7.4.12
我尝试通过设置header("Connection: close");
关闭连接,增加max_upload_size
,post_max_size
但没有用。
这可能是什么原因?
下面还给出了示例负载:
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="id"
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="category[]"
1
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="links[]"
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="title"
Test
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="tags[]"
Cat
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="gal"; filename="not.png"
Content-Type: image/png
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="desc"
<p>Test description</p>
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="links_to"
[{"id":"1","link":"photo"}]
------WebKitFormBoundaryj7GC6KVa5gPA46RP--
我最近发现问题是由于服务器中的Mod 安全规则引起的。
我通过在 modesecurity.conf
中设置 SecRuleEngine Off
禁用了 Mod 安全性,尽管这不是一个好的解决方案。如果有人知道如何在不关闭此模块的情况下执行此操作,请更新。
我已经使用 html、ajax 和 php 编写了用于上传文件以及其他表单输入的代码。我正在使用 ajax 提交表单。一切都在一台服务器上工作,但是当我将代码移动到新服务器时,我不断收到部分文件上传错误。
示例代码如下
HTML:
<form id="gal-form" class="form-gallery" enctype="multipart/form-data">
<input type="hidden" id="gal_id" name="id" value="">
<div class="up-types">
<div class="input-group mb-3 display-none check-links">
<span class="input-group-text">Links to</span>
<input type="text" value="ebooks" disabled="">
<input type="text" name="links[]" class="form-control" data-type="ebooks" id="links_to_3" value="">
</div>
<div class="input-group mb-3 display-none check-links">
<span class="input-group-text">Links to</span>
<input type="text" value="handbooks" disabled="">
<input type="text" name="links[]" class="form-control" data-type="handbooks" id="links_to_4" value="">
</div>
<div class="input-group mb-3 display-none check-links">
<span class="input-group-text">Links to</span>
<input type="text" value="manuals" disabled="">
<input type="text" name="links[]" class="form-control" data-type="manuals" id="links_to_5" value="">
</div>
</div>
<div class="form-group">
<label for="gal_title">Title</label>
<input type="text" class="form-control" id="gal_title" name="title" placeholder="Add a title here..">
</div>
<div class="form-group">
<label for="gal_title">Category</label>
<input id="gallery_tags" class="form-control" name="tags[]" type="text" value="" placeholder="Add a category here..">
</div>
<div class="form-group">
<label>File upload <span class="text-danger">*Only PDF, MP4, WEBM, OGG, JPG, JPEG, & PNG files are allowed. Please try to upload images/videos of a specific aspect ratio</span></label>
<input type="file" name="gal" id="gal-file" class="file-upload-default">
<div class="input-group col-xs-12">
<input type="text" class="form-control file-upload-info" disabled="" placeholder="Upload File">
<span class="input-group-append">
<button class="file-upload-browse btn btn-primary" type="button">Browse</button>
</span>
</div>
</div>
<div class="form-group">
<label for="event_text">Description</label>
<textarea class="form-control" id="media_desc" name="desc" rows="4" aria-hidden="true"></textarea>
</div>
<button type="submit" id="gal-button" class="btn btn-primary mr-2">Submit</button>
</form>
我要设置一些来自 javascript 的参数,所以,
$("#gal-form").on('submit', function(e) {
e.preventDefault();
var desc = "Some description here";
if ($('#gal_title').val() == '') {
$('#display-msg').html('<span style="color:red">Please enter title name...</span>');
return false;
} else if ($('#gal-file').get(0).files.length === 0 && !desc) {
$('#display-msg').html('<span style="color:red">Please enter a description or choose a file to upload...</span>');
return false;
}
var formData = new FormData(this);
var values = $("input[name='links[]']:enabled").map(function() {
let id = this.id.split("_").pop();
let link = $(this).data("type");
if (this.value) {
link += "/" + this.value;
}
return {
id: id,
link: link
};
}).get();
formData.append('links_to', JSON.stringify(values));
formData.set('desc',desc);
$.ajax({
type: 'POST',
url: 'url',
data: formData,
dataType: 'json',
contentType: false,
cache: false,
processData: false,
success: function(obj) {
if (obj.success) {
window.location.reload();
} else {
alertItem(obj.error);
}
},
error: function(request, status, error) {
alertItem(request.responseText);
}
});
});
并且在PHP,
$uploadStatus = 1;
$data = array();
if(!empty($_FILES["gal"]["name"])){
$file_name = pathinfo(basename($_FILES["gal"]["name"]),PATHINFO_FILENAME);
$fileType = pathinfo(basename($_FILES["gal"]["name"]), PATHINFO_EXTENSION);
$fileName = $this->generateSlug($file_name).'_'.time().'.'.$fileType;
$targetFilePath = $fileName;
$allowTypes = array('pdf', 'mp4', 'webm', 'ogg', 'jpg', 'png', 'jpeg');
if(in_array(strtolower($fileType), $allowTypes)){
if(move_uploaded_file($_FILES["gal"]["tmp_name"], $targetFilePath)){
$data['file'] = $fileName;
}else{
$uploadStatus = 0;
return array('error'=>$_FILES["error"]));
}
}else{
$uploadStatus = 0;
return array('error'=>'Sorry, only PDF, MP4, WEBM, OGG, JPG, JPEG, & PNG files are allowed to upload.');
}
}
if($uploadStatus == 1){
//Add to database
}
如果直接从 PHP 提交表单,上传将有效。我查看并比较了 apache 和 php 配置以检查是否有任何遗漏。下面是apache和php的服务器配置。在 Server1 和 Server2 中都可以上传。
服务器 1:
Apache/2.4.6 (RHEL 7.9)
PHP 7.3.29
服务器 2:
Apache/2.4.37 (RHEL 8.4)
PHP 7.4.19
服务器 3(新服务器):
Apache/2.4.46 (RHEL 7.9)
PHP 7.4.12
我尝试通过设置header("Connection: close");
关闭连接,增加max_upload_size
,post_max_size
但没有用。
这可能是什么原因?
下面还给出了示例负载:
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="id"
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="category[]"
1
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="links[]"
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="title"
Test
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="tags[]"
Cat
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="gal"; filename="not.png"
Content-Type: image/png
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="desc"
<p>Test description</p>
------WebKitFormBoundaryj7GC6KVa5gPA46RP
Content-Disposition: form-data; name="links_to"
[{"id":"1","link":"photo"}]
------WebKitFormBoundaryj7GC6KVa5gPA46RP--
我最近发现问题是由于服务器中的Mod 安全规则引起的。
我通过在 modesecurity.conf
中设置 SecRuleEngine Off
禁用了 Mod 安全性,尽管这不是一个好的解决方案。如果有人知道如何在不关闭此模块的情况下执行此操作,请更新。