How can I retrieve a picture from back-end

100 views Asked by At

The front-end is another server and makes API calls to back-end (Laravel) and now I want to send back a picture to front-end and show it with vanilla js (I don't know jQuery, I'm a back-end developer).
The picture must only be available to authenticated users, so I guess symbolic links are not an option.

Info:
At front-end it only shows binary content in the browser developer tool's console, and also
throws the following error:

"DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range."

I can see my picture successfully uploaded in storage/path/to/pic.

This is the Laravel controller method:

public function getAvatar(GetAvatarRequest $request): string
{
    // some code...
    //..
    //..
    return response()->file(base_path() . '/storage/app/images/avatars/1.jpeg', ['Content-Type' => 'Image/jpeg']);

    // Also tried these but no luck
    // return response()->download(Storage::disk('local')->get('images/avatars/1.jpeg'), 'name', ['Content-Type' => 'Image/jpeg']);

    // return Storage::disk('local')->get('images/avatars/1.jpeg');

    // return response()->file(Storage::disk('local')->get('images/avatars/1.jpeg'));
}

This is how I store received picture:

Storage::putFileAs('images/avatars/', $request->avatar, $request->accountId, 'private');

This is the js that handles back-end response:

let token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
let myRequest = new Request('/backend/pic');

let myHeaders = new Headers();
myHeaders.append("Accept", "application/json, text-plain, */*");
myHeaders.append("X-Requested-With", "XMLHttpRequest");
myHeaders.append("X-CSRF-TOKEN", token);
myHeaders.append("Content-Type", 'image/jpeg/jpg');

let init = {
    method: 'GET',
    mode: 'cors',
    credentials: 'same-origin',
    headers: myHeaders,
};

fetch(myRequest, init).then((response) => {
    console.log(response);
    return getBody(response);
}).then((data) => {
    console.log(data);
    createAppendElm('img', {
        'src': 'data:image/jpeg;base64,' + btoa(data),
        'alt': 'alternative'
    }, getElm('box'));
});

function getBody(response) {
    const contentType = response.headers.get("content-type");

    if (contentType && contentType.indexOf("application/json") !== -1) {
        return response.json();
    } else {
        return response.text();
    }
}

My guess is that my javascript is not handling the response properly, so any sugesstion with that?

1

There are 1 answers

2
Tim Poels On

I used the Cloudinary library, it is pretty beginner friendly and shouldn't be to difficult to figure out.