Yii2接入AWS S3管理附件(超大附件)

概述

前幾篇文章:Yii2接入AWS S3管理附件(基礎使用)Yii2接入AWS S3管理附件(分片上傳)Yii2接入AWS S3管理附件(私有附件),我們已經講解了如何上傳附件,和管理私有附件。
這篇文章我們繼續擴展如何處理超大附件。面對超大附件,比如1G的附件,即使使用分片上傳,也需要等好長時間。因爲你的附件需要先上傳到你的服務器,再從你的服務器上傳到s3。所以需要等待很長時間是肯定的了。想到這個原因,解決辦法也就有了,那我們能不能直接將附件上傳到s3,不經過服務器不就快多了嘛。

使用預簽名URL直接上傳附件到s3

s3的預簽名URL不但可以讓我訪問私有附件,也能讓我們直接上傳附件到s3。我們需要做的就是在s3Attachment組件中再增加GetPutPreSignature()方法就能獲得可以put到s3的預簽名URL。

/*
 * 獲取附件的PUT預簽名地址
 *
 * @param string $key 附件公網訪問地址.
 * @param string $content_type 附件類型.
 */
public function GetPutPreSignature($key, $content_type, $expires = '2')
{
    if (empty($key) || empty($content_type) || !is_numeric($expires)) {
        return false;
    }

    try {

        $config = [
            'region' => Yii::$app->params['S3']['region'],
            'version' => Yii::$app->params['S3']['version'],
            'credentials' => [
                'key'    => Yii::$app->params['S3']['access_key_id'],
                'secret' => Yii::$app->params['S3']['access_key_secret'],
            ],
        ];

        $sdk = new Sdk($config);

        $client = $sdk->createS3();

        $cmd = $client->getCommand('PutObject', [
            'Bucket'      => Yii::$app->params['S3Bucket'],
            'Key'         => $key,
            'ContentType' => $content_type,
            'Body'        => ''
        ]);

        $request = $client->createPresignedRequest($cmd, '+' . $expires . ' hours');

        $pre_signature_url = (string) $request->getUri();
    } catch (AwsException $e) {
        Yii::info('獲取附件的PUT預簽名地址,錯誤信息:' . $e->getMessage(), 'exception');
        return false;
    }

    return $pre_signature_url;
}

跟GetPreSignature()方法一樣,GetPutPreSignature()方法也需要指定一個過期時間,可以根據業務需要自行修改。

使用ajax通過預簽名URL上傳附件

我們已經通過GetPutPreSignature()拿到了預簽名URL,現在只需要通過ajax向該URL發起put請求就行了。

jQuery("document").ready(function($){
    $('.submit').click(function(e){
        e.preventDefault();
        
        $.ajax({
           url: url,
           method: 'PUT',
           headers: {
               'Content-Type': file.type
           },
           processData: false,
           data: file,
           success: function () {
               $('#form').submit();
           },
           error: function (error) {
               console.log(error);
           }
       });
    });
});

以上上示例代碼需要根據自身的需求修改一下。整體的想法就是點擊提交的時候,阻止表單提交,先使用ajax向我們拿到的預簽名URL發起PUT請求,將file上傳到s3。之後再提交表單。
至此Yii2通過接入AWS S3管理附件相關的功能都講解完了。如果你也遇到同樣的需求、問題,希望可以幫到你。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章