Created
July 2, 2024 09:55
-
-
Save ajaxray/5d8cd57aba4e39cc56924318ce869b8c to your computer and use it in GitHub Desktop.
Revisions
-
ajaxray created this gist
Jul 2, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,11 @@ # Upload files to object storage / CDN directly from the Frontend This is a demonstration of uploading files to S3 compliant storage. This implementation is using Laravel (backend) and AlpineJS (frontend). ### How it works 1. User selects a file on frontend 2. Javascript makes a request to the backend for getting a [TemporaryUploadUrl](https://laravel.com/docs/11.x/filesystem#temporary-upload-urls). 3. On receiving the signed, temporary URL, Javascript pushes the file to S3 directly from front-end. 4. After the upload is done, we have the CDB URL of the file (to submit and store in backend). This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,25 @@ <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; class S3DirectUploadController extends Controller { public function getTemporaryUploadUrl(Request $request) { $validatedData = $request->validate([ 'fileName' => 'required|string', ]); $fileName = $validatedData['fileName']; $path = 'direct_uploads/' . uniqid() . '-' . $fileName; ['url' => $url, 'headers' => $headers] = Storage::disk('s3')->temporaryUploadUrl( $path, now()->addMinutes(5) ); return response()->json(['url' => $url, 'filePath' => $path]); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,89 @@ <x-app-layout> <x-slot name="header"> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> {{ __('Direct CDN Upload') }} </h2> </x-slot> <div class="py-12"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> <div x-data="fileUpload()" class="p-6"> <form @submit.prevent="uploadFile"> <input type="file" x-ref="fileInput"> <button class="px-4 py-2 bg-blue-500 text-white rounded" type="submit">Upload</button> </form> <template x-if="isUploading"> <p class="p-4 text-orange-400">Uploading...</p> </template> <template x-if="uploadSuccess"> <p class="p4 text-green-600">Upload successful! File path: <span x-text="filePath"></span></p> </template> </div> </div> </div> </div> <script> function fileUpload() { return { isUploading: false, uploadSuccess: false, filePath: '', async uploadFile() { this.isUploading = true; this.uploadSuccess = false; const file = this.$refs.fileInput.files[0]; if (!file) { alert('Please select a file.'); this.isUploading = false; return; } try { // Step 1: Get temporary upload URL const response = await fetch('/upload/s3-get-upload-url', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content') }, body: JSON.stringify({ fileName: file.name }) }); const data = await response.json(); const uploadUrl = data.url; this.filePath = data.filePath; // Step 2: Upload the file to S3 using the temporary URL const uploadResponse = await fetch(uploadUrl, { method: 'PUT', headers: { 'Content-Type': file.type }, body: file }); if (uploadResponse.ok) { this.uploadSuccess = true; } else { alert('Failed to upload file.'); } } catch (error) { console.error('Error uploading file:', error); alert('An error occurred while uploading the file.'); } finally { this.isUploading = false; } } }; } </script> </x-app-layout> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,17 @@ <?php use App\Http\Controllers\S3DirectUploadController; use Illuminate\Support\Facades\Route; // Other Routes ... Route::middleware('auth')->group(function () { // Other Routes ... Route::view('/upload/s3-direct', 'upload.s3_direct'); Route::post('/upload/s3-get-upload-url', [S3DirectUploadController::class, 'getTemporaryUploadUrl']); }); require __DIR__.'/auth.php';