【问题标题】:Uploading Multipart Files with Uppy/Laravel/Vue使用 Uppy/Laravel/Vue 上传多部分文件
【发布时间】:2021-07-15 21:33:00
【问题描述】:

我正在使用Uppy's Vue components 处理上传大文件,但无法正常工作。

我遵循了 Janko here 的建议,其中包括在 Uppy 中设置 companionUrl 以指向我的服务器,然后编写必要的路由/函数来处理请求。

在我尝试触发 AWS“completeMultipartUpload”调用之前,一切正常。

$result = $client->completeMultipartUpload([
    'Bucket'          => 'bucket-name',
    'Key'             => $key,
    'UploadId'        => $uploadId,
    'MultipartUpload' => [
        'Parts' => $formattedParts,
    ],
]);

我收到以下错误:

"Error executing "CompleteMultipartUpload" on "https://bucket-name.s3.amazonaws.com/NewProject.png?uploadId=nlWLdbNgB9zgarpLBXnj17eOIGAmQM_xyBArymtwdM71fhbFvveggDmL6fz4blz.B95TLhMatDvodbMb5p2ZMKqdlLeLFoSW1qcu33aRQTlt6NbiP_dkDO90DFO.pWGH"; AWS HTTP error: Client error: `POST https://bucket-name.s3.amazonaws.com/NewProject.png?uploadId=nlWLdbNgB9zgarpLBXnj17eOIGAmQM_xyBArymtwdM71fhbFvveggDmL6fz4blz.B95TLhMatDvodbMb5p2ZMKqdlLeLFoSW1qcu33aRQTlt6NbiP_dkDO90DFO.pWGH` resulted in a `400 Bad Request` response:
    <Error><Code>InvalidPart</Code><Message>One or more of the specified parts could not be found.  The part may not have be (truncated...)
    InvalidPart (client): One or more of the specified parts could not be found.  The part may not have been uploaded, or the specified entity tag may not match the part's entity tag. - <Error><Code>InvalidPart</Code><Message>One or more of the specified parts could not be found.  The part may not have been uploaded, or the specified entity tag may not match the part's en"

我认为问题在于我尝试将找到的 JS 转换为 here 到 PHP,但是虽然它返回了一个 URL,但它不正确。显着的区别是我没有传递“UploadId”或“PartNumber”。

我搜索了 AWS 文档、Google、Stackoverflow、Ask Jeeves 等,但找不到与 "getSignedUrl" method 等效的 PHP

public function signPartUpload(Request $request, $uploadId, $partNumber)
{
    $client = new S3Client([
        'version' => 'latest',
        'region'  => 'us-east-1',
    ]);

    $key = $request->has('key') ? $request->get('key') : null;

    if (!is_string($key)) {
        return response()->json(['error' => 's3: the object key must be passed as a query parameter. For example: "?key=abc.jpg"'], 400);
    }

    if (!intval($partNumber)) {
        return response()->json(['error' => 's3: the part number must be a number between 1 and 10000.'], 400);
    }

    //Creating a presigned URL
    $cmd = $client->getCommand('PutObject', [
        'Bucket' => 'bucket-name',
        'Key' => $key
    ]);

    $response = $client->createPresignedRequest($cmd, '+20 minutes');
    $presignedUrl = (string)$response->getUri();

    return response()->json(['url' => $presignedUrl]);
}

任何帮助将不胜感激!

【问题讨论】:

    标签: php laravel vue.js amazon-s3 uppy


    【解决方案1】:

    我找到了 getSignedUrl 方法的 PHP 等效项。

    $command = $this->client->getCommand('UploadPart', [
        'Bucket'        => $this->bucket,
        'Key'           => $key,
        'PartNumber'    => $partNumber,
        'UploadId'      => $uploadId,
        'Body'          => '',
    ]);
    

    这是我的解决方案:

    /**
     * Create a pre-signed URL for parts to be uploaded to.
     * @param Request $request
     * @param string $uploadId
     * @param int $partNumber
     * @return JsonResponse
     */
    public function signPartUpload(Request $request, string $uploadId, int $partNumber)
    {
        $key = $request->has('key') ? $request->get('key') : null;
    
        // Check key
        if (! is_string($key)) {
            return response()->json(['error' => 's3: the object key must be passed as a query parameter. For example: "?key=abc.jpg"'], 400);
        }
    
        // Check part number
        if (! intval($partNumber)) {
            return response()->json(['error' => 's3: the part number must be a number between 1 and 10000.'], 400);
        }
    
        // Create the upload part command and get the pre-signed URL
        try {
            $command = $this->client->getCommand('UploadPart', [
                'Bucket'        => $this->bucket,
                'Key'           => $key,
                'PartNumber'    => $partNumber,
                'UploadId'      => $uploadId,
                'Body'          => '',
            ]);
    
            $presignedUrl = $this->client->createPresignedRequest($command, '+20 minutes');
        } catch (Exception $e) {
            return response()->json(['error' => $e->getMessage()], 400);
        }
    
        // Convert the pre-signed URL to a string
        $presignedUrlString = (string) $presignedUrl->getUri();
    
        return response()->json(['url' => $presignedUrlString]);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-28
      • 1970-01-01
      • 2018-08-26
      • 1970-01-01
      • 2020-06-30
      • 2021-01-19
      • 2013-03-02
      • 1970-01-01
      相关资源
      最近更新 更多