0

I'm trying to upload a file or image on a D9 site via json api. The test is namely to upload the user picture on the user entity.

I've been following the documentation or read questions about, but I can't get it working.

The front-end is done with Next.js.

One the test done is the following:

The front-end next calls the next.js api server:

const filename = selectedFile.name;
const fr = new FileReader();
fr.readAsArrayBuffer(selectedFile);
fr.onload = async function () {
    const arrayBuffer = fr.result;
    if (arrayBuffer && typeof arrayBuffer !== 'string') {
        const base64String = _arrayBufferToBase64(arrayBuffer);
        const cookieSession = await getUpdateCookie();
        const res = await fetch(`/api/users-test/user?cookie=${cookieSession}&name=${filename}`, {
            method: 'POST', body: base64String,
        });
    }
}

function _arrayBufferToBase64(buffer: ArrayBuffer) {
    let binary = '';
    const bytes = new Uint8Array(buffer);
    const len = bytes.byteLength;
    for (let i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
    }
    return window.btoa(binary);
}

The api next.js server post then to Drupal:

const res = await fetch(
      `${process.env.NEXT_PUBLIC_DRUPAL_BASE_URL}/jsonapi/user/user/{userID}/user_picture`,
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/octet-stream',
          Accept: 'application/vnd.api+json',
          'Content-Disposition': `name="file"; filename="${filename}"`,
          Authorization: `Bearer ${token}`,
        },
        body: req.body,
      }
    );

I tried different ways to convert the file to "binary file data", but none work: the user picture is always a blank square with an X.

However, if I try the same call with postman, the file is correctly loaded:

postman

So, for now, I hypothesize the problem is on the javascript code, while Drupal has been configured correctly.

3
  • If there is already a question then we should not need to ask it again.
    – mona lisa
    Commented May 17, 2022 at 13:08
  • @cilefen unfortunately, the code in that question did not work for me, otherwise I would have already had it working. For example, the passage via the api server Next is an extra layer that other answer do not cover.
    – Giuseppe
    Commented May 17, 2022 at 14:22
  • 1
    If it works with postman, but not with next.js, then this might be a better question on Stack Overflow, which probably has more people familiar with next.js. Commented May 17, 2022 at 15:48

1 Answer 1

0

I am currently having the same issue. The post goes thru perfectly in postman. the code snippet below is used to perform the post action in nextjs


//this function is used to convert the file

const readFileDataAsBase64 = (fl) => {
    const file = fl;

    return new Promise((resolve, reject) => {
        const reader = new FileReader();

        reader.onload = (event) => {
          console.log('here')
            resolve(event.target.result);
        };

        reader.onerror = (err) => {
            reject(err);
        };

        reader.readAsDataURL(file);
    });
}

//get the value of the file converted to binary
const filedata= await readFileDataAsBase64(values.files[0]);

//call the post file function to perform the post
const resfile = await postFiles(
      'http://the-url',
      filedata,
      values.files[0].name
    );

const postFiles = (url, body, filename) => {

    const myPost = async() => {
        try {
         const res = await fetch(url, {
              method: 'POST',
              body: body,
              headers: {
                'Content-Type': 'application/octet-stream',
                'Content-Disposition': `file; filename=${filename}`,
                'api-key': 'myapi-key',
              },
            });
        } catch (err){
        }
  
    } 
    postData();
  
  };

This file isn't being posted to drupal. Did anyone found a solution to properly post a file using the api

3
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented May 24, 2022 at 2:50
  • For now, I've found 2 points: 1. there was probably a CORS problem, so I had to configure it. See e.g. drupal.org/node/3024331#comment-13261556 2. There is some problem in the call between the "next front-end" and the "next server". If I post the image via a plain JS or directly from the "next front-end" it works, so the problem is most likely there.
    – Giuseppe
    Commented Jun 1, 2022 at 9:49
  • I solved the issue. The post wasn't working with fetch, but axios works fine.
    – msd026
    Commented Jun 1, 2022 at 23:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.