redux-toolkit: RTK Query - Setting headers doesn't work

I’m trying to send a POST request and I need to set the ‘content-type’ header to ‘application/json’, I’m using fetchBaseQuery and it’s supposed to automatically do that but it’s not working because when I check the sent request using Chrome Dev Tools and checking the request headers I don’t see ‘content-type’ set to ‘application/json’. I don’t see it at all so I tried to manually do that by either using prepareHeaders like this

// Or from '@reduxjs/toolkit/query' if not using the auto-generated hooks
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

// initialize an empty api service that we'll inject endpoints into later as needed
export const mainApi = createApi({
  reducerPath: "mainApi",
  baseQuery: fetchBaseQuery({
    baseUrl: "http://localhost:5000/api/v1/",
    prepareHeaders: (headers) => {
      headers.set("Content-Type", "application/json");
      console.log(headers);
      return headers;
    },
  }),
  endpoints: () => ({}),
});

it still won’t work, btw console.log(headers) only returns an empty Headers object . I also tried to set the header like this

    addUser: builder.mutation({
      query: (data) => {
        //  console.log(typeof body);
        return {
          url: `auth/signup`,
          method: "POST",
          headers: { "content-type": "application/json" },
          body: JSON.stringify(data),
        };
      },
    }),

I still can’t see the ‘content-type’ header when checking it using browser dev tools.

image

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 4
  • Comments: 27 (9 by maintainers)

Most upvoted comments

99% it’s CORS. Does the server declare to the browser that the browser is allowed to send these headers? Do you see an error message?

I checked all of the cors issues, it wasn’t that. I have fixed it though, turns out it is my own code.

Basically, I changed the prepareHeaders to an async function. The function was returning the value before the promise had been resolved.

 prepareHeaders: async (headers) => {
      // get auth token and append headers
      const token = await auth.currentUser?.getIdToken()
      headers.set('x-id-token', token as string)
   
      return headers
    }

Thank you for your help! 😃

BTW, when I remove mode: "no-cors" from fetchBaseQuery, I see this(content-type: application/json suddenly appears):

image

But the request fails:

image

Thanks for the quick response @phryneas!

I think that your comment here correctly identified this issue (and clarified that it pertains to SuperTokens, not RTK Query).

Therefore I would consider this issue out of scope to RTK query and closable here, (fixing the SuperTokens implementation of their fetch wrapper is now covered by this issue.

@anmilleriii that looks like that “modified fetch” just does not support getting passed a Request object as the first argument.

The first argument to fetch has to be a RequestInfo which is either a string, or a Request class instance.

Supertokens fails to implement the standard there.

If any of those can create a reproduction (keep in mind, we need a client and server for this!) we can give feedback.
But like this it’s impossible to say anything about this.
You could all have the same problem, you could have completely different problems that just manifest in the same way 🤷‍♂️

Hello, having a smiliar issue with POST/PATCH/PUT. However this is not caused by any cors settings (have tested). Using the rtk code gen @rtk-query/codegen-openapi and with my empty api set up as below, I can clearly see the prepareHeaders function is called properly (although it is an empty map), however the header is never actually set.

  baseQuery: fetchBaseQuery({
    baseUrl: API_BASE_URL,
    paramsSerializer: (params) => {
      return toMetaParams(params as IMeta, true);
    },
    prepareHeaders: (headers) => {
      headers.set('Content-Type', 'application/json');
      console.log(headers);
      return headers;
    }
  }),
  endpoints: () => ({})
});

In that case, this is browser behaviour and has nothing to do with RTK Query. RTK Query just calls fetch - and you would probably observe the same behaviour if you would call fetch manually by yourself. I’d suggest you try that to get to a point where the normal fetch call works and then go back into using RTK Query here.

Generally: CORS problems like this have to be solved at the server side - the server has to send headers that indicate that a requerst of this kind is allowed.

I have a similar problem to @mohamedamara1’s.

export const loginApi = createApi({
  reducerPath: "loginApi",
  baseQuery: fetchBaseQuery({
    prepareHeaders: (headers) => {
      headers.set("Content-Type", "application/json");
      headers.set("accept", "text/plain");
      return headers;
    },
    mode: "no-cors",
    baseUrl: process.env.REACT_APP_MOBILE_DEV_BASE_URL
  }),
  endpoints: (builder) => ({
    login: builder.mutation<UserResponse, LoginRequest>({
      query: (credentials) => ({
        url: "login",
        method: "POST",
        body: credentials
      })
    })
  })
});

The requested format of Content-Type on the server is application/json. But the code does not set the appropriate value for Content-Type header, and leaves text/plain;charset=UTF-8 instead(throwing error 415: unsupported media type). What could I change to set the needed Content-Type: application/json for the request header?