ecyrbe/zodios

No Content-Type if requestFormat "json"

AlexeyMatskevich opened this issue · 7 comments

I create the client this way:

const endpoints = makeApi([
  {
    method: "post",
    path: "/reviewer/auth/oauth/slack",
    alias: "getAuthorizeUrl",
    requestFormat: "json",
    response: z.object({authorize_url: z.string()}),
  },
])

export const api = new Zodios(endpoints)

Then I make a query that looks like this in the browser:
request:

POST /reviewer/auth/oauth/slack HTTP/2
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0
Accept: application/json, text/plain, */*
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
Referer: https://localhost/reviewer/login
Origin: https://localhost
DNT: 1
Connection: keep-alive
Cookie: reviewer=AYefNZEwmKBQis713PGC-VHtDTC8BJGE5Cr4cLOb82AdvqNiW0Sij1SAbCYmbhCfwLOwZvbjjgYnbOGm6dtBUW_LpNuzf0C_R5OJnDWgELu3kfXCbG8ddVkgMt6wyFfp6lleYARMfpQgk_HJTj4-RgHOu2g_eafgZVRxYq4DNUKGLi0FVtjmyeu3_uj13iCmfb5qZlYvdaYbDUnzNwYogSLgZEumisCJNFCyuFbwrSpDulM04Yf3S2KTyCztzqgH2t5vvX1UfEusd07v_KSziqc%3D
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Content-Length: 0

response:

HTTP/2 302 Found
alt-svc: h3=":443"; ma=2592000
content-type: text/html
location: /
server: Caddy
set-cookie: reviewer=AW7-L8L8lBsRZIWdLDn0cK88vPS1mGTfOJX3VgcAe3MaE2DknCSBmZRT0ix6ouXL-w_a0Yv_2LdFRhqv05cALmI9sLElqFI1HG-JtFBQVK-N5GgeMdggFHBIwk-bBa9wvTHof6-xZmEjGM0Ey53Z-rZdo1wyVgVo9aEdmbzfTL7lxUe2qNoX-Mu0c9DOZGJ3OOaJ2YvphBKf3Mu5CKCYsW8lpfIx60qinIseAStXoxY8HNaTEu1IdotnkOJ_WI2k-0_vKhlHUKLcC_Xr5VU4t2o%3D; path=/; secure; HttpOnly; SameSite=Lax
content-length: 0
date: Fri, 28 Jul 2023 12:43:49 GMT
X-Firefox-Spdy: h2

I expect the content type to be spelled out in the query as application/json.
The header with content type is missing, causing my backend to not accept the request as a json request. What can I do about it?

I have a hunch that the lack of a request body, causes this behavior, because a similar request with a request body has a content type.

ecyrbe commented

Are you using zodios axios or fetch ?

I use axios

ecyrbe commented

I see you are not sending any content in your request. That's why there is no content type.
And the request is correctly saying it accepts json.
But the accept tells that we also accept anything.
So that's not the missing content type at fault, but accept being too large.
Will check this, must be axios defaults here that cause the issue.

I tried prescribing Accept this way:

 const { mutate, data: authorizeUrl, isLoading } = apiHooks.useGetAuthorizeUrl(
    {
        headers:
            {
              'Accept': 'application/json'
            }
    }
)

I'm using React Query.
The header is passed, but the backend doesn't see the request as json and returns html.
Content-Type transmissions are similarly ignored.

ecyrbe commented

This is odd.
Can you share :

  • zodios version used
  • axios version used

if you are using any plugins ?

About versions:

  '@zodios/core':
    specifier: ^10.9.2
    version: 10.9.2(axios@1.4.0)(zod@3.21.4)
  '@zodios/plugins':
    specifier: ^10.6.0
    version: 10.6.0(@zodios/core@10.9.2)(axios@1.4.0)
  '@zodios/react':
    specifier: ^10.4.5
    version: 10.4.5(@tanstack/react-query@4.32.0)(@zodios/core@10.9.2)(react@18.2.0)
  axios:
    specifier: ^1.4.0
    version: 1.4.0

And I use this plugin:

export function createAuthPlugin(
  isAuthenticated: boolean,
  setIsAuthenticated: Dispatch<SetStateAction<boolean>>
) {
  const zodiosAuthPlugin: ZodiosPlugin = {
    name: "authPlugin",

    response: async (api, config, response) => {
      if (isAuthenticated && response.status === 401) {
        console.log('set not isAuthenticated');
        console.log(isAuthenticated);
        setIsAuthenticated(false);
      }

      return response
    },
  }

  return zodiosAuthPlugin
}

const zodiosAuthPlugin = createAuthPlugin(
  isAuthenticated,
  setIsAuthenticated
);
  
apiClient.use(zodiosAuthPlugin);

I tried to use pluginFetch for the sake of experimentation, and directly write the Content-Type with React Query Hooks (like here), it worked.

request:
POST /reviewer/auth/oauth/slack HTTP/2
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0
Accept: application/json, text/plain, */*
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
Referer: https://localhost/reviewer/login
content-type: application/json
Origin: https://localhost
DNT: 1
Connection: keep-alive
Cookie: reviewer=AaaUN9bCAuFh9GF84U4UAXRJC16Y3DB-Kg988GuU8BqvCRgIgbi_yy1tRl1_9pAvLnosVI-YhiGdzPiSZwwvnYS30L8SSAJ_AOYAQupIKqYvxBkeyI5O89x8p_AOngf7ogUKYKq2FSru64aYl6O0lWqWAPx8m31CD2gv1M_Qr9mbt87_OGo5Fdg4QTS_OrT-tC4wflcLFrqr0Btvivec2t4BzALZW_X3KrEhGCXuY7UNjUY5uwMnv0SFR7ZR3hXyWnoakeUXG4lT0k6UdaU1t1XAE9TSEzkFM08BTZYW1byFjU2VbKzaHKiKia4S-W_hO2B0rIIaEGtWW9Nzw5dYqiZ6qHbrROZ9ByD9HtfXdKIpZNYMoRs_oYBvRdsPHpTVo0q97f8ZfPYSXaaoX7apI5JO8XLX3jkZS9rv6LarvkMP4Bn0A3dlKnysyLfjY_I2rATZ3DL7XL12QHgGqvR_SMG3U1nObI5tpzbtx0QETsY4
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Content-Length: 0
TE: trailers

response:
HTTP/2 200 OK
alt-svc: h3=":443"; ma=2592000
content-type: application/json
server: Caddy
set-cookie: reviewer=Ac4GAyok3PyXj8gCIDmwTM-Dzik6ek3oqstQCCKfSUROozenNOYmT8smxZk3Xrloq792iyfvh2DVJUv21JGZQbEqWVAkcLmnUuyFeFznr-sG31TD4cOGiU2MBot25G8G8s1GocEahJIzDaMk3a3o_ZILYlpB3lm-HaS8o9iHcVD9qSSknTURmPqrdEztxuLQoE-U5bapCK0EESXmlIaMapIeFij1b1lFI0RAq5Hg_0TGoHgeeVtQUFTGvZ-_L9vWY4GRHQOwATD8kNW793WJWVVoxYegN21y3BZz48C4b7VenzPJ3XjiuoCGYYtQETG8Ja2X6LtJODAkQGmmGotxRXIaRSqWUNupeqnG-pGKakHBdyP_LCBGqQRUJEJdU4c9m_TN_kHmV9edAeRKnhjchpP138ezPyH6Z84dtgabkzt7aS0D2ZaMfaVd9ISQY9fvKvd-8PEqUjxcvQonNGawx6Z3cQhzT7ljflHL0-6I7W-W; path=/; secure; HttpOnly; SameSite=Lax
content-length: 276
date: Tue, 01 Aug 2023 06:06:13 GMT
X-Firefox-Spdy: h2

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.