How to use alicloud oss to upload large files in pieces
It's very easy to upload large files, but there are various problems in doing it. I just made one. Now record the process
demand
The company's new project needs to do a large file upload function, which saves some engineering project models and other things online. The G-files can't be saved on its own server at any time. Use Alibaba cloud's oss service. During this period, I experienced the following methods
Method 1: upload the file from the client to the server. The server then uploads to oss in pieces, which has been implemented,
Disadvantages:
1: The file occupies the server bandwidth during the upload process.
2: Large files uploaded by users may not be deleted in time. They become garbage files on the server and occupy the system disk. You need to write another scheduled task script to clear.
Advantage: sensitive data is not exposed.
Method 2: upload directly on the web, which has been realized.
Disadvantages: temporary key and secret will be exposed to the client, with certain risks.
Advantages: it does not occupy server resources and directly interacts with oss.
Method 1: save and upload at the back end
Using webuploader plug-in to upload fragments to oss
Plug in content first
<script src="/public/others/jquery.js"></script> <script src="/public/webuploader/webuploader.js"></script> <link rel ="slylesheet" type="text/css" href="/public/webuploader/webuploader.css">
html code part
<div class="demo"> <div id="uploadfile"> <!--Used to store file information--> <div id="the_2655" class="uploader-list"></div> <div class="form-group form-inline"> <div id="pick_2655" style="float:left">Select file</div> <button id="Btn_2655" class="btn btn-default" style="padding: 5px 10px;border-radius: 3px;">Start upload</button> </div> </div> </div>
js part
//Upload file function //ids unique ID //folder file save directory function uploadfiles(ids,folder) { $(function(){ var $list = $("#the_"+ids); $btn = $("#Btn_"+ids); var uploader = WebUploader.create({ resize: false, // Uncompressed image swf: '__PUBLIC__/ueditor/third-party/webuploader/uploader.swf', // swf file path server: '{:url("admin/upload/uploadFile")}', // File receiving server. pick: "#pick_"+ids, // Button to select a file. Optional chunked: true, //Do you want to slice large file uploads chunkSize:5*1024*1024, //Slice upload, 2M for each slice, 5M by default //fileSizeLimit: 6*1024* 1024 * 1024, / / the total size limit of all files is 6G fileSingleSizeLimit: 10*1024* 1024 * 1024, // Single file size limit 5 G formData: { folder:folder //Custom parameters } //auto: false / / select whether to upload the file automatically // Chunkretry: 2, / / if an error occurs in a partition due to network problems, the number of automatic retransmissions is allowed //runtimeOrder: 'html5,flash', // accept: { // title: 'Images', // extensions: 'gif,jpg,jpeg,bmp,png', // mimeTypes: 'image/*' // } }); // When a file is added to the queue uploader.on( 'fileQueued', function( file ) { $list.append( '<div id="' + file.id + '" class="item">' + '<h4 class="info">' + file.name + '</h4>' + '<p class="state">Waiting to upload...</p>' + '</div>' ); }); // Create progress bar to display in real time during file upload. uploader.on( 'uploadProgress', function( file, percentage ) { var $li = $( '#'+file.id ), $percent = $li.find('.progress .progress-bar'); // Avoid duplicate creation if ( !$percent.length ) { $percent = $('<div class="progress progress-striped active">' + '<div class="progress-bar" role="progressbar" style="width: 0%">' + '</div>' + '</div>').appendTo( $li ).find('.progress-bar'); } $li.find('p.state').text('Uploading'); $percent.css( 'width', percentage * 100 + '%' ); }); // File uploaded successfully uploader.on( 'uploadSuccess', function( file,response) { $( '#'+file.id ).find('p.state').text('Uploaded'); $list.append('<input type="hidden" name="'+ids+'" value="'+response.filePath+'" />'); //alert(response.filePath); }); // File upload failed, display upload error uploader.on( 'uploadError', function( file ) { $( '#'+file.id ).find('p.state').text('Upload error'); }); // Finish uploading uploader.on( 'uploadComplete', function( file ) { $( '#'+file.id ).find('.progress').fadeOut(); }); $btn.on('click', function () { if ($(this).hasClass('disabled')) { return false; } uploader.upload(); // if (state === 'ready') { // uploader.upload(); // } else if (state === 'paused') { // uploader.upload(); // } else if (state === 'uploading') { // uploader.stop(); // } }); }); }
Note that the file size of each slice in the demo is 5M, and the maximum limit parameter in the ini file of PHP is greater than 5M, so the upload can be successful. If you want to modify it, go to Baidu.
php part
/** * Upload file function, if upload fails to print$_ FILES array, view error message * Value: 0; no error occurred, file upload succeeded. * Value: 1; the uploaded file exceeds php.ini Medium upload_ max_ The value limited by the filesize option. * Value: 2; the size of the uploaded file exceeds the max in the HTML form_ FILE_ The value specified by the size option. * Value: 3; only part of the file is uploaded. * Value: 4; no files uploaded. * date:2018.4.18 from:zhix.net */ public function uploadFile(){ header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Content-type: text/html; charset=gbk32"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); $folder = input('folder'); if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { exit; // finish preflight CORS requests here } if ( !empty($_REQUEST[ 'debug' ]) ) { $random = rand(0, intval($_REQUEST[ 'debug' ]) ); if ( $random === 0 ) { header("HTTP/1.0 500 Internal Server Error"); exit; } } // header("HTTP/1.0 500 Internal Server Error"); // exit; // 5 minutes execution time set_time_limit(5 * 60); // Uncomment this one to fake upload time usleep(5000); // Settings $targetDir = './Public'.DIRECTORY_SEPARATOR.'file_material_tmp'; //Store temporary directory of slices if($folder){ $uploadDir = './Public'.DIRECTORY_SEPARATOR.'file_material'.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR.date('Ymd'); }else{ $uploadDir = './Public'.DIRECTORY_SEPARATOR.'file_material'.DIRECTORY_SEPARATOR.date('Ymd'); //Partition and merge storage directory } $cleanupTargetDir = true; // Remove old files $maxFileAge = 5 * 3600; // Temp file age in seconds // Create target dir if (!file_exists($targetDir)) { mkdir($targetDir,0777,true); } // Create target dir if (!file_exists($uploadDir)) { mkdir($uploadDir,0777,true); } // Get a file name if (isset($_REQUEST["name"])) { $fileName = $_REQUEST["name"]; } elseif (!empty($_FILES)) { $fileName = $_FILES["file"]["name"]; } else { $fileName = uniqid("file_"); } $oldName = $fileName; $fileName = iconv('UTF-8','gb2312',$fileName); $filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName; // $uploadPath = $uploadDir . DIRECTORY_SEPARATOR . $fileName; // Chunking might be enabled $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0; $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 1; // Remove old temp files if ($cleanupTargetDir) { if (!is_dir($targetDir) || !$dir = opendir($targetDir)) { die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory111."}, "id" : "id"}'); } while (($file = readdir($dir)) !== false) { $tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file; // If temp file is current file proceed to the next if ($tmpfilePath == "{$filePath}_{$chunk}.part" || $tmpfilePath == "{$filePath}_{$chunk}.parttmp") { continue; } // Remove temp file if it is older than the max age and is not the current file if (preg_match('/\.(part|parttmp)$/', $file) && (filemtime($tmpfilePath) < time() - $maxFileAge)) { unlink($tmpfilePath); } } closedir($dir); } // Open temp file if (!$out = fopen("{$filePath}_{$chunk}.parttmp", "wb")) { die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream222."}, "id" : "id"}'); } if (!empty($_FILES)) { if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) { die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file333."}, "id" : "id"}'); } // Read binary input stream and append it to temp file if (!$in = fopen($_FILES["file"]["tmp_name"], "rb")) { die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream444."}, "id" : "id"}'); } } else { if (!$in = fopen("php://input", "rb")) { die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream555."}, "id" : "id"}'); } } while ($buff = fread($in, 4096)) { fwrite($out, $buff); } fclose($out); fclose($in); rename("{$filePath}_{$chunk}.parttmp", "{$filePath}_{$chunk}.part"); $index = 0; $done = true; for( $index = 0; $index < $chunks; $index++ ) { if ( !file_exists("{$filePath}_{$index}.part") ) { $done = false; break; } } if ($done) { $pathInfo = pathinfo($fileName); $hashStr = substr(md5($pathInfo['basename']),8,16); $hashName = time() . $hashStr . '.' .$pathInfo['extension']; $uploadPath = $uploadDir . DIRECTORY_SEPARATOR .$hashName; if (!$out = fopen($uploadPath, "wb")) { die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream666."}, "id" : "id"}'); } //flock($hander,LOCK_EX) document lock if ( flock($out, LOCK_EX) ) { for( $index = 0; $index < $chunks; $index++ ) { if (!$in = fopen("{$filePath}_{$index}.part", "rb")) { break; } while ($buff = fread($in, 4096)) { fwrite($out, $buff); } fclose($in); unlink("{$filePath}_{$index}.part"); } flock($out, LOCK_UN); } fclose($out); $response = [ 'success'=>true, 'oldName'=>$oldName, 'filePath'=>$uploadPath, // 'fileSize'=>$data['size'], 'fileSuffixes'=>$pathInfo['extension'], //File suffix // 'file_id'=>$data['id'], ]; return json($response); } // Return Success JSON-RPC response die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}'); }
The back end receives fragmentation and composes files. Pay attention to several points
1: The header of the method should be limited by utf8, as follows, otherwise the file name will be garbled in Chinese
2: The return path is an absolute path, which you can intercept according to the needs of the project.
header("Content-type: text/html; charset=utf-8");
File upload:
<?php if (is_file(__DIR__ . '/../autoload.php')) { require_once __DIR__ . '/../autoload.php'; } if (is_file(__DIR__ . '/../vendor/autoload.php')) { require_once __DIR__ . '/../vendor/autoload.php'; } use OSS\OssClient; use OSS\Core\OssException; // Alicloud primary account AccessKey has access to all APIs, which is very risky. It is strongly recommended that you create and use RAM account for API access or daily operation and maintenance. Please log in https://ram.console.aliyun.com Create a RAM account. $accessKeyId = "<yourAccessKeyId>"; $accessKeySecret = "<yourAccessKeySecret>"; // The Endpoint takes Hangzhou as an example. Please fill in other regions according to the actual situation. $endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; $bucket= "<yourBucketName>"; $object = "<yourObjectName>"; $file = "<yourLocalFile>"; $options = array( OssClient::OSS_CHECK_MD5 => true, OssClient::OSS_PART_SIZE => 1, ); try{ $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint); $ossClient->multiuploadFile($bucket, $object, $file, $options); } catch(OssException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n");
Pay attention to the multiuploadFile method, which is the specific encapsulation method of piecemeal upload. Alicloud piecemeal upload is to upload a specific file. Alicloud does not admit every piece of your own, so do not try to upload the piecemeal file yourself.
Refer to the link for specific usage:
Alicloud php oss fragment upload description document
Upload the result reference document.
Method 2, web front-end direct transmission
The problem with web direct delivery is that STS temporary authorized access
You need to understand this thing
Specifically, Alibaba cloud creates a sub account with the permission of oss. The sub account with the permission of oss is equivalent to a new RAM role. Through this sub account and the id and secret generated when the role is created, a temporary token can be obtained. Through this token, the front end can perform some operations without the permission of the general account. The specific process of creating a sub account can be seen in the above link. The permissions given can be used by the front end according to your actual situation.
A detour
Alicloud provides an interface document for obtaining STS temporary authorization,
Alibaba cloud acquires sts
Note that version 2015-04-01 here fails to work. The error is as follows:
sts.aliyuncs.comInvalidVersionSpecified parameter Version is not valid.
The reply to the work order is as follows:
I'm dnmd. Why can't you hang here? Whose time is wasted?
Attachment: method of requesting interface:
class STS { protected $url = 'https://sts.aliyuncs.com'; protected $accessKeySecret = '1234567890qwertyuioasdfghj'; protected $accessKeyId = 'LT11234567898'; protected $roleArn = 'acs:ram::$accountID:role/$roleName';//Specify the role's ARN, role policy permission protected $roleSessionName = 'client1';//User defined parameters. This parameter is used to distinguish different token s and can be used for user level access audit. Format: ^ [a-zA-Z0-9 \@\-_ + $ protected $durationSeconds = '1800';//Specified expiration time protected $type = 'xxx';//Get different permissions when calling conveniently public function __construct($type) { $this->type = $type; $this->setRoleArn(); } public function sts() { $action = 'AssumeRole';//Get token through role-playing interface date_default_timezone_set('UTC'); $param = array( 'Format' => 'JSON', 'Version' => '2015-04-01', 'AccessKeyId' => $this->accessKeyId, 'SignatureMethod' => 'HMAC-SHA1', 'SignatureVersion' => '1.0', 'SignatureNonce' => $this->getRandChar(8), 'Action' => $action, 'RoleArn' => $this->roleArn, 'RoleSessionName' => $this->roleSessionName, 'DurationSeconds' => $this->durationSeconds, 'Timestamp' => date('Y-m-d') . 'T' . date('H:i:s') . 'Z' //'policy' = [1jeemaa1] / / this parameter can limit the permissions of the generated STS token. If not specified, the returned token has all the permissions of the specified role. ); $param['Signature'] = $this->computeSignature($param, 'POST'); $res = CurlHandle::httpPost($this->url, $param);//curl post request if ($res) { return self::_render($res); } else { return []; } } private static function _render($res) { $res = json_decode($res, true); if (empty($res['Credentials'])) { return []; } else { return [ 'accessKeySecret' => $res['Credentials']['AccessKeySecret'] ?? '', 'accessKeyId' => $res['Credentials']['AccessKeyId'] ?? '', 'expiration' => $res['Credentials']['Expiration'] ?? '', 'securityToken' => $res['Credentials']['SecurityToken'] ?? '', ]; } } protected function computeSignature($parameters, $setMethod) { ksort($parameters); $canonicalizedQueryString = ''; foreach ($parameters as $key => $value) { $canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value); } $stringToSign = $setMethod . '&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1)); $signature = $this->getSignature($stringToSign, $this->accessKeySecret . '&'); return $signature; } public function getSignature($source, $accessSecret) { return base64_encode(hash_hmac('sha1', $source, $accessSecret, true)); } protected function percentEncode($str) { $res = urlencode($str); $res = preg_replace('/\+/', '%20', $res); $res = preg_replace('/\*/', '%2A', $res); $res = preg_replace('/%7E/', '~', $res); return $res; } public function getRandChar($length) { $str = null; $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"; $max = strlen($strPol) - 1; for ($i = 0; $i < $length; $i++) { $str .= $strPol[rand(0, $max)];//rand($min,$max) generates a random integer between min and Max } return $str; } protected function setRoleArn() { if ($this->type == '123') {//Different strategies are used according to the input parameters. Of course, there are other ways of writing that are compatible with more strategies $this->roleArn = 'acs:ram::123456789098:role/=$roleName'; } } }
The right light
You still need to use the sdk. However, this sdk is the sdk of this module that Alibaba cloud has already packaged, which is 10000 times better than the one you downloaded from github. If you want to use tp, you can put it under vendor. If you want to use laravel, you can use it normally.
SDK download link of STS
Import project after download
Simple token request method,
1: Note that the expiration time is 3600s by default,
2: Accesskeysecret and accesskeyid are the parameters of the sub account you created, not the total account.
<?php namespace app\services; class StsService { protected $url = 'https://sts.aliyuncs.com'; protected $accessKeySecret; protected $accessKeyId; protected $roleArn;//Specify the role's ARN, role policy permission protected $roleSessionName = 'client';//User defined parameters. This parameter is used to distinguish different token s and can be used for user level access audit. Format: ^ [a-zA-Z0-9 \@\-_ + $ protected $durationSeconds = '3600';//Specified expiration time public function __construct() { $this->accessKeySecret = config('oss_sts_accessKeySecret'); $this->accessKeyId = config('oss_sts_accessKeyId'); $this->roleArn = config('oss_sts_roleArn'); } public function getStsOuah() { require_once VENDOR_PATH.'aliyuncs/sts-server/aliyun-php-sdk-core/Config.php'; $iClientProfile = \DefaultProfile::getProfile("cn-hangzhou", $this->accessKeyId, $this->accessKeySecret); $client = new \DefaultAcsClient($iClientProfile); $request = new \Sts\Request\V20150401\AssumeRoleRequest(); $request->setRoleSessionName("client_name"); $request->setRoleArn($this->roleArn); // $request->setPolicy(VENDOR_PATH.'aliyuncs/sts-server/policy/bucket_write_policy.txt'); $request->setDurationSeconds($this->durationSeconds); $response = $client->doAction($request); $rows = array(); $body = $response->getBody(); $content = json_decode($body); if ($response->getStatus() == 200){ $rows['statusCode'] = 200; $rows['accessKeyId'] = $content->Credentials->AccessKeyId; $rows['accessKeySecret'] = $content->Credentials->AccessKeySecret; $rows['expiration'] = $content->Credentials->Expiration; $rows['securityToken'] = $content->Credentials->SecurityToken; }else{ $rows['statusCode'] = 500; $rows['errorCode'] = $content->Code; $rows['errorMessage'] = $content->Message; } return $rows; } }
The returned data needs to be passed to the front end
Array ( [statusCode] => 200 [accessKeyId] => STS.NT3aC8UXWJydcuuoyreGfvWxJ [accessKeySecret] => 59vT1iGHaJtEiyDwpEN9125ZgBJ4eShfUbtnXiGvQirb [expiration] => 2020-06-06T06:11:20Z [securityToken] => CAIS9QF1q6Ft5B2yfSjIr5eGKvmMuId2/buzYVPEi3k2achKmZLTqDz2IHlPdHlrBOwesv8/lGFY7fwblqJ4T55IQ1Dza8J148z5Be4Lo8yT1fau5Jko1beHewHleTOZsebWZ+LmNqC/Ht6md1HDkAJq3LL+bk/Mdle5MJqP+/UFB5ZtKWveVzddA8pMLQZPsdITMWCrVcygKRn3mGHdfiEK00he8TonsPXhn5fEskSF3QOhlbAvyt6vcsT+Xa5FJ4xiVtq55utye5fa3TRYgxowr/4t3PwfpGuf4orNUwgBuE/fKYnd/thuKh5kYLM6Gr71cwRkHn730xqAARfcIG9I3u0E7TJzfmTvcIIIpogdqzjed27c1JvZAoAxHu+6XgIBgrbcLds0q2InwBPKWF4S0nfKnI9kXPn1CXtKdjQmgLW0cRz0w9/OfbxTIX9lb2HmtWABxvLVAgQtHJRb4o6xxgkQy5pBs3BeHYJ1yY9NZCDu5zW2OGC03MqZ )
Front end code:
I'm not a professional front-end. Let's make do with the style.
html
<div id="up_wrap"></div> <div class="form-group"> <input type="file" id="file" multiple="multiple" /> </div> <div class="form-group"> <input type="button" class="btn btn-primary" id="file-button" value="Upload" /> <input type="button" class="btn btn-primary" id="Continue-button" value="Continue" /> </div>
js
<script src="http://gosspublic.alicdn.com/aliyun-oss-sdk-6.0.2.min.js"></script> <script type="text/javascript"> var appServer = 'http://www.tele.bh/med/home/sts';//Get the interface of ststoken. This is my local address. Your interface address should be clear var bucket = 'Your new bucket name'; var region = 'oss-cn-hangzhou';//Selected when creating a new bucket. var uid = 'x';//User ID. It depends on your situation var Buffer = OSS.Buffer; console.log(OSS); //Get the authorization STSToken and initialize the client var applyTokenDo = function (func) { var url = appServer; return $.get(url).then(function (result) { var res = JSON.parse(result); var creds = res.data.Credentials; console.log(creds); var client = new OSS({ region: region, accessKeyId: creds.AccessKeyId, accessKeySecret: creds.AccessKeySecret, stsToken: creds.SecurityToken, bucket: bucket }); return func(client); }); }; //Upload file var uploadFile = function (client) { if (upfiles.length < 1) return; upfile = upfiles[0]; var file = upfile.file; //key can be customized as a file name (for example file.txt )Or directory (for example, abc/test/file.txt )To upload files to the current Bucket or the specified directory under the Bucket. var key = upfile.name; var objkey = key + "_" + uid + ".json"; return client.multipartUpload(key, file, { progress: function (p, cpt, res) { console.log("p:", p); console.log("cpt:", cpt); if (cpt != undefined) { var content = JSON.stringify(cpt); client.put(objkey, new Buffer(content)); } console.log(Math.floor(p * 100) + '%'); var bar = document.getElementById('progress-bar_' + upfile.num); bar.style.width = Math.floor(p * 100) + '%'; bar.innerHTML = Math.floor(p * 100) + '%'; } }).then(function (res) { console.log('upload success: ', res); upfiles.shift(); client.delete(objkey); applyTokenDo(uploadFile); }).catch(function(err) { console.log(err); error(err); }); }; //Breakpoint resume file var reUploadFile = function (client) { if (upfiles.length < 1) return; upfile = upfiles[0]; var file = upfile.file; //key can be customized as a file name (for example file.txt )Or directory (for example, abc/test/file.txt )To upload files to the current Bucket or the specified directory under the Bucket. var key = upfile.name; var objkey = key + "_" + uid + ".json"; return client.get(objkey).then(function (res) { var data = JSON.parse(res.content); data.file = file; return client.multipartUpload(key, file, { checkpoint: data, progress: function (p, cpt, res) { console.log("p:", p); console.log("cpt:", cpt); if (cpt != undefined) { var content = JSON.stringify(cpt); client.put(objkey, new Buffer(content)); } var bar = document.getElementById('progress-bar_' + upfile.num); bar.style.width = Math.floor(p * 100) + '%'; bar.innerHTML = Math.floor(p * 100) + '%'; } }).then(function (ret) { console.log('upload success:', ret); upfiles.shift(); client.delete(objkey); applyTokenDo(uploadFile); }).catch(function(err) { console.log(err); error(err); }); }); }; function error(err){ switch (err.status) { case 0: if (err.name == "cancel") { //Manually click to pause upload return; } break; case -1: //Request error, auto upload again // Upload again; return; case 203: //Callback failed // The front end calls back to the back end; return; case 400: switch (err.code) { case 'FilePartInterity': //File Part changed case 'FilePartNotExist': //File Part does not exist case 'FilePartState': //File Part obsolete case 'InvalidPart': //Invalid Part case 'InvalidPartOrder': //Invalid part order case 'InvalidArgument': //Parameter format error // Clear the breakpoint; // Upload again; return; case 'InvalidBucketName': //Invalid Bucket name case 'InvalidDigest': //Invalid summary case 'InvalidEncryptionAlgorithmError': //The specified entropy coding encryption algorithm is wrong case 'InvalidObjectName': //Invalid Object name case 'InvalidPolicyDocument': //Invalid Policy document case 'InvalidTargetBucketForLogging': //Invalid target bucket in Logging operation case 'MalformedXML': //Illegal XML format case 'RequestIsNotMultiPartContent': //Illegal Post request content type // Reauthorization; // Continue to upload; return; case 'RequestTimeout'://request timeout // Upload again; return; } break; case 403: //Invalid authorization, reauthorization case 411: //Missing parameter case 404: //Bucket/Object/Multipart Upload ID does not exist // Reauthorization; // Continue to upload; return; case 500: //OSS internal error // Upload again; return; default: break; } } //File upload queue var upfiles = []; $(function () { //Initialize file upload queue $("#file").change(function (e) { var ufiles = $(this).prop('files'); var htm = ""; for (var i = 0; i < ufiles.length; i++) { htm += "<dl><dt>" + ufiles[i].name + "</dt><dd><div class=\"progress\"><div id=\"progress-bar_" + i + "\" class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\"0\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"min-width: 2em;\">0%</div></div></dd></dl>"; upfiles.push({ num: i, name: ufiles[i].name, file: ufiles[i] }) } console.log('upfiles:', upfiles); $("#up_wrap").html(htm); }); //upload $("#file-button").click(function () { applyTokenDo(uploadFile); }); //Sequel $("#Continue-button").click(function () { applyTokenDo(reUploadFile); }) }) </script>
After the fragment upload is completed, the folder link with uploadId will be returned and uploaded to the backend.
Pay attention to a few points,
1: When setting the permissions of roles, you need to give put and delete permission, otherwise js will report an error.
2: Cross domain access: access control allow origin header is required for role setting to allow cross domain access.
Comprehensive description
The function is not so difficult. The problem is that either the documents provided by Alibaba cloud are not easy to use, or the sdk is difficult to use. I also synthesized several documents from Baidu before I came out. I hope you can avoid detours in the future.