spatie / laravel-medialibrary

Associate files with Eloquent models
https://spatie.be/docs/laravel-medialibrary
MIT License
5.78k stars 1.08k forks source link

cors blocked after adding media conversion #3391

Closed inagamov closed 1 year ago

inagamov commented 1 year ago

i serve frondend vue app (prod: https://testing.example.ru. dev: http://localhost:9000) the backend laravel app is served on (prod: https://api-testing.example.ru. dev: http://example.test)

i've already had storing method in my MediaController.php that worked without cors issue

public function store (Request $request): jsonResponse
    {
        $modelType = $request->input('model_type');
        $modelId = $request->input('model_id');
        $collection = $request->input('collection');

        $unsplash_image_data = $request->input('unsplash_image_data');

        $model = $modelType::findOrFail($modelId);
        $media = $model;

        // add from unsplash
        if ($unsplash_image_data) {
            $media = $media
                ->addMediaFromUrl($unsplash_image_data['urls']['regular'])
                ->usingName($unsplash_image_data['slug']);

        // upload from the computer
        } else {
            $media = $media
                ->addMediaFromRequest('file')
                ->usingName($request->file('file')->getClientOriginalName())
                ->usingFileName(uniqid() . '.' . $request->file('file')->getClientOriginalExtension());
        }

        $media = $media->toMediaCollection($collection);

        return $this->jsonResponse($media->toArray());
    }

however, after i've added register media conversions method to user model, the cors get blocked. i have this issue only on production. on local it works just fine.

User.php

class User extends Authenticatable implements HasMedia
{
    use HasApiTokens, HasFactory, Notifiable, InteractsWithMedia;

    public function registerMediaConversions(Media $media = null): void
    {
        $this->addMediaConversion('preview')
            ->optimize()
            ->nonQueued()
            ->width(1920)
            ->height(1080);
    }

cors.php

    'paths' => ['api/*', 'sanctum/csrf-cookie', 'storage/*', 'media/*'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['*'],
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => true,

api.php

Route::middleware('auth:sanctum')->group(function () {
    Route::post('/media', [MediaController::class, 'store']);
});

upload file request

const uploadFile = async (event) => {
  isLoading.value = true;

  const file = event.target.files[0];

  const formData = new FormData();
  formData.append("file", file);
  formData.append("model_type", "App\\Models\\User");
  formData.append("model_id", user.value.id);
  formData.append("collection", "avatar");

  api
    .post("/media", formData, {
      headers: {
        "Content-Type": "multipart/form-data",
      },
    })
    .then((response) => {
      form.value.reset();
      user.value.avatar = response.data;

      $q.notify({
        message: t("user.profile.form.avatar.success.upload"),
        icon: "r_done",
      });
    })
    .catch((error) => {
      $q.notify({
        message: error.response.data.message,
        color: "red",
        icon: "r_crisis_alert",
      });
    })
    .finally(() => {
      isLoading.value = false;
    });
};

ps: i've setup cors & sanctum, they work without issues. please tell me what i'm doing wrong because cors block only when i have media conversions

also, i've noticed that i get the same error if i try to use spatie/image-optimizer

Spatie\Image\Image::load($media->getPath())
    ->width(2048)
    ->save('image.jpg');

maybe its the issue with accessing path on the server? but why cors error appears? im doing everything on the back and it shouldn't have restrictions like frontend...