I have an API with Laravel 10 and I am trying to get an image I have saved in the public/images folder.
This is my function in the controller:
public function show()
{
$imageUrl = asset('images/myimage.png');
return response()->json(['imageUrl' => $imageUrl]);
}
This is my API:
Route::get('images', [ImageController::class, 'show']);
Route::post('images', [ImageController::class, 'store']);
Using POSTMAN, the response to http://127.0.0.1:8000/api/images
is:
{
"imageUrl": "http://127.0.0.1:8000/images/myimage.png"
}
And if I open that url with POSTMAN or the browser, I can see the image perfectly. However, when I try to get the image in my frontend app (with Angular 15) I am getting a CORS error:
Access to XMLHttpRequest at 'http://127.0.0.1:8000/images/myimage.png' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
My cors config file is like this:
<?php
return [
'paths' => ['api/*', 'images/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
I also tried to edit the Kernel.php like this but no success:
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Http\Middleware\HandleCors::class
],
'images' => [
\Illuminate\Http\Middleware\HandleCors::class
]
];
protected $middlewareAliases = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
In my Angular project, I also added a proxy config file for this API:
{
"/api/*": {
"target": "http://localhost:8000",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
},
"/images/*": {
"target": "http://localhost:8000",
"secure": false,
"logLevel": "debug"
}
}
And the function I use to make the request in Angular:
getImage(): Observable<Blob> {
const headers = new HttpHeaders({ 'Content-Type': 'image/png' });
return this.http.get('http://127.0.0.1:8000/images/myimage.png', { headers, responseType: 'arraybuffer' }).pipe(
map((response: ArrayBuffer) => {
return new Blob([response], { type: 'image/png' });
})
);
}
I have been reading about CORS issues with Laravel, but most of the results are about creating a middleware CORS file or using Fruitcake, which are now not needed because Laravel 10 has the CORS file by default.
Am I missing something? Thanks!