sindresorhus / ky

🌳 Tiny & elegant JavaScript HTTP client based on the Fetch API
MIT License
13.62k stars 363 forks source link

POST request fails in Astro.js API route #534

Closed intermundos closed 1 month ago

intermundos commented 11 months ago

Hello all,

I am encountering an issue where HTTP POST requests are failing in Astro.js API route. The request is sent to Directus API.

The following request is failing with status 400 bad request.

            const response = await ky.post( 'http://127.0.0.1:8055/auth/login', {
                json: {
                    email: body.email,
                    password: body.password
                },
            } ).json()
DEBUG: Invalid payload. "email" is required.
    err: {
      "type": "",
      "message": "Invalid payload. \"email\" is required.",
      "stack":
          DirectusError: Invalid payload. "email" is required.
              at file:///directus/node_modules/.pnpm/file+api/node_modules/@directus/api/dist/auth/drivers/local.js:66:19
      "name": "DirectusError",
      "extensions": {
        "reason": "\"email\" is required"
      },
      "code": "INVALID_PAYLOAD",
      "status": 400
    }

Same request with Got or native fetch works as expected.

Many thanks in advance for your help.

sholladay commented 11 months ago

Your code looks fine to me.

We can narrow down the problem a little bit if you try each of these and tell me what happens:

  1. Without .json()

    const response = await ky.post( 'http://127.0.0.1:8055/auth/login', {
                json: {
                    email: body.email,
                    password: body.password
                },
            } )
  2. Using body instead of json option

    const response = await ky.post( 'http://127.0.0.1:8055/auth/login', {
                body: JSON.stringify({
                    email: body.email,
                    password: body.password
                }),
            } ).json()
  3. Using body instead of json option and without .json()

    const response = await ky.post( 'http://127.0.0.1:8055/auth/login', {
                body: JSON.stringify({
                    email: body.email,
                    password: body.password
                }),
            } )

I don't know if Director requires a Content-Type: application/json header or if it just assumes it, but you might need to add that header to snippets 2 & 3 above since the body option is being used.

sindresorhus commented 11 months ago

Can you try out https://github.com/sindresorhus/ky/releases/tag/v1.1.1 ?

i-geobot commented 10 months ago

Pardon for the belated reply.

The issue was related to node version that handled headers incorrectly. Upgrading node fixed it.

Many thanks for support and time!

phoenisx commented 7 months ago

I feel this issue resembles mine as well.

I am using this library on NodeJS v20.9, and found out that sending a .post() request using this library didn't work. The headers was always set to text/plan. I tried forcefully setting the content-type header to application/json, but it didn't change. Not sure why even after setting the headers it's getting passed as text/plain 🤔

To give more context, my setup includes Sveltekit and a Fastify Backend, both running on NodeJS v20.9. The issue doesn't happen when I replace it with axios. but I can replicate it with NodeJs's native fetch function as well.

havgry commented 7 months ago

Have you tried setting content-length manually? See https://github.com/sindresorhus/ky/issues/514

sholladay commented 1 month ago

The issue doesn't happen when I replace it with axios. but I can replicate it with NodeJs's native fetch function as well.

If it happens with native fetch then it's unlikely we can solve it here.

Since @intermundos has not replied, I'm going to close this for now. If anyone has a reproducible example that is broken with Ky but works with fetch, please do let us know.