Git Product home page Git Product logo

laravel-uppy-s3-multipart-upload's Introduction

Multipart Uploads using Laravel, AWS S3, and Uppy

Latest Version on Packagist PHPStan Total Downloads

Upload large files directly to AWS S3 using Laravel (backend) and Uppy (frontend).

Appearance

upload00

upload01

upload02

Installation

Install the package via Composer

composer require tapp/laravel-uppy-s3-multipart-upload

Add required JS libraries

Add on your package.json file the Uppy JS libraries and AlpineJS library:

    ...
    "devDependencies": {
        "alpinejs": "^3.11.1",
        ...
    },
    "dependencies": {
        "@uppy/aws-s3-multipart": "^3.1.2",
        "@uppy/core": "^3.0.5",
        "@uppy/drag-drop": "^3.0.1",
        "@uppy/status-bar": "^3.0.1"
        ...
    }
    ...

Add in your resources/js/bootstrap.js file:

...

require('@uppy/core/dist/style.min.css')
require('@uppy/drag-drop/dist/style.min.css')
require('@uppy/status-bar/dist/style.min.css')

import Uppy from '@uppy/core'
import DragDrop from '@uppy/drag-drop'
import StatusBar from '@uppy/status-bar'
import AwsS3Multipart from '@uppy/aws-s3-multipart'

window.Uppy = Uppy
window.DragDrop = DragDrop
window.StatusBar = StatusBar
window.AwsS3Multipart = AwsS3Multipart

Add in your resources/js/app.js:

...
import Alpine from 'alpinejs';

window.Alpine = Alpine;

Alpine.start();

Install the JS libraries:

for Mix:

npm install
npm run dev

for Vite:

npm install
npm run build

You can use CDNs for Uppy and AlpineJS, if you prefer.

Publish config file

Publish the config file with:

php artisan vendor:publish --tag=uppy-s3-multipart-upload-config

This is the contents of the published config file:

return [
    's3' => [
        'bucket' => [
            /*
             * Folder on bucket to save the file
             */
            'folder' => '',
        ],
        'presigned_url' => [
            /*
             * Expiration time of the presigned URLs
             */
            'expiry_time' => '+1 hour',
        ],
    ],
];

Publish view file

php artisan vendor:publish --tag=uppy-s3-multipart-upload-views

AWS S3 Setup

This package installs the AWS SDK for PHP and use Laravel's default s3 disk configuration from config/filesystems.php file.

You just have to add your S3 keys, region, and bucket using the following env vars in your .env file:

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=
AWS_BUCKET=

Warning

The AWS_URL or AWS_POST_END_POINT env vars should only be set when using a custom, non-aws endpoint. For more details please refer to this issue: #14.

To allow direct multipart uploads to your S3 bucket, you need to add some extra configuration on bucket's CORS configuration. On your AWS S3 console, select your bucket. Click on "Permissions" tab. On "CORS configuration" add the following configuration:

[
    {
        "AllowedHeaders": [
            "Authorization",
            "x-amz-date",
            "x-amz-content-sha256",
            "content-type"
        ],
        "AllowedMethods": [
            "PUT",
            "POST",
            "DELETE",
            "GET"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "ETag"
        ]
    }
]

On AllowedOrigins:

"AllowedOrigins": [
    "*"
]

You should list the URLs allowed, e.g.:

"AllowedOrigins": [
    "https://example.com"
]

https://uppy.io/docs/aws-s3-multipart/#S3-Bucket-Configuration

https://uppy.io/docs/aws-s3/#S3-Bucket-configuration

Add S3 Transfer Acceleration

To use S3 transfer acceleration, enable it by adding a AWS_USE_ACCELERATE_ENDPOINT=true env var on your .env file, and add 'use_accelerate_endpoint' => env('AWS_USE_ACCELERATE_ENDPOINT') in s3 options on your config/filesystems.php:

       's3' => [
            ...
            'use_accelerate_endpoint' => env('AWS_USE_ACCELERATE_ENDPOINT'),
        ],

Configuration

You can configure the folder to upload the files and the expiration of the presigned URLs used to upload the parts, with the config/uppy-s3-multipart-upload.php file:

return [
    's3' => [
        'bucket' => [
            /*
             * Folder on bucket to save the file
             */
            'folder' => 'videos',
        ],
        'presigned_url' => [
            /*
             * Expiration time of the presigned URLs
             */
            'expiry_time' => '+30 minutes',
        ],
    ],
];

Endpoints added

This package add the following routes:

POST    /s3/multipart
OPTIONS /s3/multipart
GET     /s3/multipart/{uploadId}
GET     /s3/multipart/{uploadId}/{partNumber}
POST    /s3/multipart/{uploadId}/complete
DELETE  /s3/multipart/{uploadId}

Usage

Add a hidden field for the uploaded file url

Add a hidden input form element on your blade template. When the upload is finished, it will receive the url of the uploaded file:

E.g.:

<input type="hidden" name="file" id="file" />

Add the uppy blade component to your blade view:

<x-input.uppy />

Passing data to the uppy blade component

Hidden field name

Use the hiddenField attribute to provide the name of the hidden field that will receive the url of uploaded file:

$hiddenField = 'image_url';
<x-input.uppy :hiddenField="$hiddenField" />

The file name will be used if none is provided.

Uppy Core Options

https://uppy.io/docs/uppy/#Options

You can pass any uppy options via options attribute:

<x-input.uppy :options="$uppyOptions" />

Uppy core options are in this format:

$uppyOptions = "{
    debug: true,
    autoProceed: true,
    allowMultipleUploads: false,
}";

Default core options if none is provided:

{
    debug: true,
    autoProceed: true,
    allowMultipleUploads: false,
}

Uppy Status Bar Options

https://uppy.io/docs/status-bar/#Options

You can pass any uppy status bar options via statusBarOptions attribute:

<x-input.uppy :statusBarOptions="$uppyStatusBarOptions" />

Uppy Status Bar options are in this format:

$uppyStatusBarOptions = "{
    target: '.upload .for-ProgressBar',
    hideAfterFinish: false,
}";

Default status bar options if none is provided:

{
    target: '.upload .for-ProgressBar',
    hideAfterFinish: false,
}

Uppy Drag & Drop Options

https://uppy.io/docs/drag-drop/#Options

You can pass any uppy drag & drop options via dragDropOptions attribute:

<x-input.uppy :dragDropOptions="$uppyDragDropOptions" />

Uppy Drag & Drop options are in this format:

$uppyDragDropOptions = "{
    target: '.upload .for-DragDrop',
}";

Default drag & drop options if none is informed:

{
    target: '.upload .for-DragDrop',
}

Upload Element Class

Use the uploadElementClass attribute to provide the class of the HTML element used for upload:

$imageClass = 'images';
<x-input.uppy :uploadElementClass="$imageClass" />

The upload class will be used if none is provided.

Multiple Uppy Instances

If you want to use multiple Uppy instances, add a different uploadElementClass attribute to each instance. E.g.:

<!-- First Uppy instance for image uploads -->
<div>
    <input type="hidden" name="images" id="images" />
    <x-input.uppy :options="$imageOptions" :hiddenField="$imageField" :uploadElementClass="$imageClass" />
</div>


<!-- Second Uppy instance for video uploads -->
<div>
    <input type="hidden" name="videos" id="videos" />
    <x-input.uppy :options="$videoOptions" :hiddenField="$videoField" :uploadElementClass="$videoClass" />
</div>

Note from Uppy docs: "If multiple Uppy instances are being used, for instance, on two different pages, an id should be specified. This allows Uppy to store information in localStorage without colliding with other Uppy instances." Learn more here.

Extra JavaScript to onUploadSuccess

If you need to add extra JavaScript code on onUploadSuccess function, use the extraJSForOnUploadSuccess attribute:

E.g.:

$extraJSForOnUploadSuccess = "
    document.getElementById('saveImageButton').removeAttribute('disabled');
    document.getElementById('saveImageButton').click();
"
<x-input.uppy :extraJSForOnUploadSuccess="$extraJSForOnUploadSuccess" />

Default extraJSForOnUploadSuccess value is empty string.

Clear caches

Run:

php artisan optimize
php artisan view:clear

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

If you discover any security-related issues, please email [email protected].

Credits

Libraries used in this package:

License

The MIT License (MIT). Please see License File for more information.

laravel-uppy-s3-multipart-upload's People

Contributors

andreia avatar kaptk2 avatar kerkness avatar swilla avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-uppy-s3-multipart-upload's Issues

Tapp\LaravelUppyS3MultipartUpload\Http\Controllers\UppyS3MultipartController::encodeURIComponent(): Argument #1 ($str) must be of type string, null given

Hi there,

First of all, congrats for the initiative, perfect package!

Now, I've had my log full of this particular issue:

Tapp\LaravelUppyS3MultipartUpload\Http\Controllers\UppyS3MultipartController::encodeURIComponent(): Argument #1 ($str) must be of type string, null given

Full stack:
[2023-05-07 21:25:19] production.ERROR: Tapp\LaravelUppyS3MultipartUpload\Http\Controllers\UppyS3MultipartController::encodeURIComponent(): Argument #1 ($str) must be of type string, null given, called in /home/forge/office.motorcyclesports.net/vendor/tapp/laravel-uppy-s3-multipart-upload/src/Http/Controllers/UppyS3MultipartController.php on line 339 {"exception":"[object] (TypeError(code: 0): Tapp\\LaravelUppyS3MultipartUpload\\Http\\Controllers\\UppyS3MultipartController::encodeURIComponent(): Argument #1 ($str) must be of type string, null given, called in /home/forge/office.motorcyclesports.net/vendor/tapp/laravel-uppy-s3-multipart-upload/src/Http/Controllers/UppyS3MultipartController.php on line 339 at /home/forge/office.motorcyclesports.net/vendor/tapp/laravel-uppy-s3-multipart-upload/src/Http/Controllers/UppyS3MultipartController.php:30) [stacktrace] #0 /home/forge/office.motorcyclesports.net/vendor/tapp/laravel-uppy-s3-multipart-upload/src/Http/Controllers/UppyS3MultipartController.php(339): Tapp\\LaravelUppyS3MultipartUpload\\Http\\Controllers\\UppyS3MultipartController->encodeURIComponent() #1 /home/forge/office.motorcyclesports.net/vendor/tapp/laravel-uppy-s3-multipart-upload/src/Http/Controllers/UppyS3MultipartController.php(301): Tapp\\LaravelUppyS3MultipartUpload\\Http\\Controllers\\UppyS3MultipartController->getSignedUrl() #2 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): Tapp\\LaravelUppyS3MultipartUpload\\Http\\Controllers\\UppyS3MultipartController->signPartUpload() #3 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(43): Illuminate\\Routing\\Controller->callAction() #4 /home/forge/office.motorcyclesports.net/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Routing/TracingControllerDispatcherTracing.php(21): Illuminate\\Routing\\ControllerDispatcher->dispatch() #5 /home/forge/office.motorcyclesports.net/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Routing/TracingRoutingDispatcher.php(31): Sentry\\Laravel\\Tracing\\Routing\\TracingControllerDispatcherTracing->Sentry\\Laravel\\Tracing\\Routing\\{closure}() #6 /home/forge/office.motorcyclesports.net/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Routing/TracingControllerDispatcherTracing.php(20): Sentry\\Laravel\\Tracing\\Routing\\TracingRoutingDispatcher->wrapRouteDispatch() #7 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Routing/Route.php(259): Sentry\\Laravel\\Tracing\\Routing\\TracingControllerDispatcherTracing->dispatch() #8 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\\Routing\\Route->runController() #9 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Routing/Router.php(798): Illuminate\\Routing\\Route->run() #10 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}() #11 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #12 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Routing/Router.php(797): Illuminate\\Pipeline\\Pipeline->then() #13 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Routing/Router.php(776): Illuminate\\Routing\\Router->runRouteWithinStack() #14 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Routing/Router.php(740): Illuminate\\Routing\\Router->runRoute() #15 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Routing/Router.php(729): Illuminate\\Routing\\Router->dispatchToRoute() #16 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(200): Illuminate\\Routing\\Router->dispatch() #17 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}() #18 /home/forge/office.motorcyclesports.net/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestIpMiddleware.php(45): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #19 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Sentry\\Laravel\\Http\\SetRequestIpMiddleware->handle() #20 /home/forge/office.motorcyclesports.net/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestMiddleware.php(30): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #21 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Sentry\\Laravel\\Http\\SetRequestMiddleware->handle() #22 /home/forge/office.motorcyclesports.net/app/Http/Middleware/LocaleHeader.php(18): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #23 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): App\\Http\\Middleware\\LocaleHeader->handle() #24 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #25 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle() #26 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle() #27 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #28 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle() #29 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle() #30 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #31 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle() #32 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #33 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle() #34 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(62): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #35 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Http\\Middleware\\HandleCors->handle() #36 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #37 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Http\\Middleware\\TrustProxies->handle() #38 /home/forge/office.motorcyclesports.net/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Middleware.php(52): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #39 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Sentry\\Laravel\\Tracing\\Middleware->handle() #40 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}() #41 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(175): Illuminate\\Pipeline\\Pipeline->then() #42 /home/forge/office.motorcyclesports.net/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter() #43 /home/forge/office.motorcyclesports.net/public/index.php(51): Illuminate\\Foundation\\Http\\Kernel->handle() #44 {main} "}

I am using Laravel 10.

Any idea of might be causing this?

Best regards

Variable not initialized

Hi great package, very helpful.. Thanks a lot.

I was wondering where the $partResponse['NextPartNumberMarker'] is being initialized at line 172. My IDE flags it as not initialized, even though this being a recursive call.

private function listPartsPage($key, $uploadId, $partIndex, $parts = null)
{
$parts = $parts ?? collect();
$results = $this->client->listParts([
'Bucket' => $this->bucket,
'Key' => $key,
'UploadId' => $uploadId,
'PartNumberMarker' => $partIndex,
]);
if ($results['Parts']) {
$parts = $parts->concat($results['Parts']);
if ($results['IsTruncated']) {
$results = $this->listPartsPage($key, $uploadId, $partResponse['NextPartNumberMarker'], $parts);
$parts = $parts->concat($partResponse['Parts']);
}
}

File validation (backend)

Hi there :)

First of all, thanks for providing this!

Is there a way to validate the file type on the server? I couldn't find anything in the source for this :)

Thanks!

Other s3 Providers?

I tried to get this to work with DigitalOcean and I can't seem to. It continues to post to s3 even when I update the aws_url to something else. Is it possible to make this work?

It doesn't work with uppy v2

Uppy Companion V2, now handles, signature batching. Unfortunately I don't have time to contribute but I wish...
This will solve your issue in your controller and make it Uppy 2 compatible:

public function prepareUploadPart(Request $request, $uploadId, $batch)
{
    $key = $this->encodeURIComponent($request->input('key'));

    $partNumbers = explode(",", $request->partNumbers);

    $urls = [];
    foreach ($partNumbers as $partNumber) {
        $command = $this->client->getCommand('uploadPart', [
            'Bucket'     => $this->bucket,
            'Key'        => $key,
            'UploadId'   => $uploadId,
            'PartNumber' =>  (int) $partNumber,
            'Body'       => '',
        ]);

        $urls[$partNumber] = (string) $this->client->createPresignedRequest($command, '+2 hour')->getUri();
    }

    return response()
        ->json([
            'presignedUrls' => $urls,
        ]);
}

Headless support

Would like to configure this as kind of a headless companion for uppy. In my case the client is a detached react app which authenticates with the laravel API using sanctum/tokens

Instead of using web routes, I would like to use API routes with the 'auth:sanctum' middleware. Would it be of interest to submit a PR with these modifications. Perhaps adding middleware/guard details to the config?

Laravel 9 support

Trying to install this on a Laravel 9 project but get the following composer error:

  Problem 1
    - Root composer.json requires tapp/laravel-uppy-s3-multipart-upload ^0.4.0 -> satisfiable by tapp/laravel-uppy-s3-multipart-upload[v0.4.0].
    - tapp/laravel-uppy-s3-multipart-upload v0.4.0 requires illuminate/contracts ^8.0 -> found illuminate/contracts[v8.0.0, ..., 8.x-dev] but these were not loaded, likely because it conflicts with another require.

Any chance we can get illuminate/contracts upgraded to v9?

createMultipartUpload throwing aws Host override error

A new issue popped up after doing a fresh deploy which appears to result from updates with the AWS SDK but unclear to me if this new error is on the Uppy side of things, the laravel side of things or with AWS itself.

The call to $this->client->createMultipartUpload in UppyS3MultipartController (line 103) is throwing the error Host override cannot be combined with Dualstack, FIPS, or S3 Accelerate from AWS.

There doesn't appear to be a lot of details on this error. I'm curious if others are getting it as my uploading has been very stable for many months with no changes.

Also, the exception being thrown does not support $exception->getStatusCode() which needs to be removed from the try/catch in order to see the actual error from AWS.

Error if AWS_USE_ACCELERATE_ENDPOINT=true (works fine if FALSE)

Project based on Laravel 10.

If in the .env file I enable: AWS_USE_ACCELERATE_ENDPOINT=true
After browsing for a file, uploader throws an error.

And works fine when: AWS_USE_ACCELERATE_ENDPOINT=false

RESPONSE:

"message": "Call to undefined method Aws\Exception\UnresolvedEndpointException::getStatusCode()",
"exception": "Error",
"file": "...\vendor\tapp\laravel-uppy-s3-multipart-upload\src\Http\Controllers\UppyS3MultipartController.php",
"line": 122,
"trace": [
{
"file": "...\vendor\laravel\framework\src\Illuminate\Routing\Controller.php",
"line": 54,
"function": "createMultipartUpload",
"class": "Tapp\LaravelUppyS3MultipartUpload\Http\Controllers\UppyS3MultipartController",
"type": "->"
}

HEADERS:

{
"POST": {
"scheme": "http",
"host": "127.0.0.1:8000",
"filename": "/s3/multipart",
"remote": {
"Address": "127.0.0.1:8000"
}
}
}
{
"Status": "500Internal Server Error",
"Version": "HTTP/1.1",
"Transferred": "11.57 kB (11.29 kB size)",
"Referrer Policy": "strict-origin-when-cross-origin",
"DNS Resolution": "System"
}

Uppy is not a constructor

I tried to follow the instructions only difference being I used the CDNs and uppy doesn't show up in the console I'm getting this error any ideas I'm using this CDN <script src="https://releases.transloadit.com/uppy/v2.0.2/uppy.min.js"></script> and <script src="//unpkg.com/alpinejs" defer></script>

Uncaught TypeError: Uppy is not a constructor at eval (eval at <anonymous> (alpinejs:5:599), <anonymous>:27:26) at alpinejs:5:936 at Vt (alpinejs:1:4604) at w (alpinejs:5:79) at alpinejs:5:27365 at Function.<anonymous> (alpinejs:5:10229) at r (alpinejs:5:1652) at n (alpinejs:5:1682) at Qt (alpinejs:5:1692) at S (alpinejs:5:4344) at alpinejs:5:3867 at Array.forEach (<anonymous>) at Object.nr [as start] (alpinejs:5:3855) at alpinejs:5:32510

Incompatable with latest version of Uppy

When Uppy version 3 is installed like this:

"@uppy/aws-s3-multipart": "^3.1.2",
"@uppy/core": "^3.0.5",
"@uppy/drag-drop": "^3.0.1",
"@uppy/status-bar": "^3.0.1",

a 404 error is thrown as soon as a file is uploaded.

Using version 2.0.2 as recommend in the documentation works.

Thanks from the Drupal community!

Not an issue, but wanted to say thank you! This has helped us create a module for the Drupal community. Your excellent documentation in the controller allowed for a smooth port and easy understanding of all the required parts.

The module is still in the works but when it is complete, I'll post an update.

Much appreciated and well done!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.