Fatal error: Uncaught Aws\S3\Exception\InvalidRequestException: AWS Error Code: InvalidRequest,Status Code: 400,AWS Request ID: B1A28EBE65521DF4,AWS Error Type: client,AWS Error Message: You must specify at least one part,User-Agent: aws-sdk-PHP2/2.7.22 Guzzle/3.9.2 curl/7.40.0 PHP/5.6.6 thrown in C:\vhosts********.com\db*****\FileUploader_v2\aws\Aws\Common\Exception\NamespaceExceptionFactory.PHP on line 91
每当我使用AWS S3运行我的分段上传程序时,我都会收到上述错误.我的程序应该在JS脚本中切片部分文件,然后使用XMLHTTPRequest将其发送到PHP脚本.这部分似乎运作良好.但是,调用CompleteMultipartUpload时会出现问题.我从错误中收集到的是我的部分太小或空洞.
的Upload.htm:
var命令;
var文件;
var ownerName;
var totalSize;
var partSize = 2 * 1024 * 1024; // 不变
var sendBackData;
var totalSize;
var sureUploadSize = 0,probableUplaodSize = 0;
var numParts;
var partsLeft = [];
function _(el){ return document.getElementById(el); } function calcTotalSize(file){ var size_total = 0; for(var i = 0; i < file.length; i++){ size_total += file[i].size; } return size_total; } function uploadFile(){ file = _("file").files[0]; console.log(file); ownerName = _("name").value; totalSize = file.size; command = 'CreateMultipartUpload'; var formdata = new FormData(); formdata.append("command",command); formdata.append("filename",file.name); formdata.append("name",ownerName); var ajax = new XMLHttpRequest(); ajax.open("POST","FileUploader.PHP",true); ajax.send(formdata); ajax.onreadystatechange = function() { if (ajax.readyState === 4) { sendBackData = JSON.parse(ajax.responseText); numParts = Math.ceil(totalSize / partSize); uploadPart(1); } }; } function uploadPart(partNum){ console.log("Uploading part " + partNum); console.log(sendBackData['uploadId']); command = 'UploadPart'; if (partNum > numParts) { completeMultipartUpload(); return; } var formdata = new FormData(); var start = (partNum - 1) * partSize; var end = start + partSize; if (end > totalSize) end = totalSize; var length = end - start; var curBlobPart = file.slice(start,end); //console.log(sendBackData['uploadId']); formdata.append("file[]",curBlobPart); formdata.append("command",command); formdata.append("uploadId",sendBackData['uploadId']); formdata.append("key",sendBackData['key']); formdata.append("partNumber",partNum); var ajax = new XMLHttpRequest(); ajax.open("POST",true); ajax.addEventListener("load",completeHandler,false); ajax.addEventListener("error",errorHandler,false); ajax.addEventListener("abort",abortHandler,false); ajax.send(formdata); ajax.onreadystatechange = function() { if (ajax.readyState === 4) { uploadPart(partNum + 1); } }; } function completeMultipartUpload() { command = 'CompleteMultipartUpload'; var formdata = new FormData(); formdata.append("command",sendBackData['key']); var ajax = new XMLHttpRequest(); ajax.open("POST",false); ajax.send(formdata); ajax.onreadystatechange = function() { if (ajax.readyState === 4) { alert("File uploaded successfully"); } }; } function progressHandler(event){ _("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total; var percent = (event.loaded / event.total) * 100; _("progressBar").value = Math.round(percent); _("status").innerHTML = Math.round(percent)+"% uploaded... please wait"; } function completeHandler(event){ _("status").innerHTML = event.target.responseText; _("progressBar").value = 0; } function errorHandler(event){ _("status").innerHTML = "Upload Failed"; } function abortHandler(event){ _("status").innerHTML = "Upload Aborted"; }`
FileUploader.PHP:
`
//require 'SimpleImage.PHP'; //require 'gifsplit.PHP'; //require 'functions.PHP'; require 'config.PHP'; require 'aws/aws-autoloader.PHP'; use Aws\Common\Exception\MultipartUploadException; use Aws\S3\Model\MultipartUpload\UploadBuilder; use Aws\S3\S3Client; use Aws\S3\Exception\S3Exception; function sendJson($arr) { header('Content-Type: application/json'); die(json_encode($arr)); } // S3 $s3 = S3Client::factory(array( 'key' => AWS_KEY,'secret' => AWS_SECRET_KEY )); //$part = $_POST['part']; switch ($_POST['command']) { case 'CreateMultipartUpload': $key = "other/".$_POST['name']."/".$_POST['filename']; $response = $s3->createMultipartUpload(array( 'Bucket' => TMP_IMG,'Key' => $key )); $uploadId = $response['UploadId']; sendJson(array( 'uploadId' => $uploadId,'key' => $key )); break; case 'UploadPart': var_dump($_FILES['file']); $result = $s3->uploadPart(array( 'Bucket' => TMP_IMG,'Key' => $_POST['key'],'UploadId' => $_POST['uploadId'],'PartNumber'=> $_POST['partNumber'],'Body' => $_FILES['file']['tmp_name'] )); break; case 'CompleteMultipartUpload': $partsModel = $s3->listParts(array( 'Bucket' => TMP_IMG,'UploadId' => $_POST['uploadId'] )); $model = $s3->completeMultipartUpload(array( 'Bucket' => TMP_IMG,'Key' => $_POST['key'],'UploadId' => $_POST['uploadId'],'Parts' => $partsModel['Parts'] )); sendJson(array( 'success' => true )); break; case 'AbortMultipartUpload': # code... break; default: # code... break; }
我完成任务有什么明显错误吗?我唯一的想法是我的部分尺寸太小,无法上传.如果是这种情况,我确实有一个解决方案,我正在研究的另一个项目版本.
$completeParams = Array( 'Bucket' => $multipartUpload['Bucket'],'Key' => $multipartUpload['Key'],'MultipartUpload' => Array( 'Parts' => $parts,),'UploadId' => $multipartUpload['UploadId'] ); $res = $client->completeMultipartUpload($completeParams);
这很好用.至少在使用SDK的第3版时. SDK的第2版预期部件直接在$params中.
*我不会透露多少分钟