Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useFetch POST with headers and body does not pass headers properly (node v18) #14268

Closed
ostapoff opened this issue Jul 4, 2022 · 2 comments
Closed

Comments

@ostapoff
Copy link

ostapoff commented Jul 4, 2022

Environment

  • Operating System: Darwin
  • Node Version: v18.3.0
  • Nuxt Version: 3.0.0-rc.4
  • Package Manager: [email protected]
  • Builder: vite
  • User Config: -
  • Runtime Modules: -
  • Build Modules: -

Reproduction

<script lang="ts" setup>
const { data } = await useFetch('/api/call', {
  key: 'my-data',
  headers: useRequestHeaders(['cookie']),
  method: 'POST',
  body: { id: 123 }
});
</script>

Describe the bug

When body is passed to the post the headers arrive to the API handler as follows (event.req.headers) as a Map object:

Headers {
  host: undefined,
  [Symbol(headers list)]: HeadersList {
    [Symbol(headers map)]: Map(3) {
      'cookie' => 'xxxxxxxxxxxxxxxxxxx',
      'content-type' => 'application/json',
      'accept' => 'application/json'
    },
    [Symbol(headers map sorted)]: null
  },
  [Symbol(guard)]: 'none'
}

In this case it is not possible to access the passed headers by key (event.req.headers.keyname) and use the composables like useCookie.

When the body is not defined the headers arrive as a plain object:

{
  cookie: 'xxxxxxxxxxxxxxxxxxx',
  host: undefined
}

This happens only running the 18th Node. On earlier 16th the headers arrive as a plain object.

Found workaround

a server middleware fixes the problem by converting a map into a plain object

export default defineEventHandler(async (event) => {
  if (event.req.headers.constructor.name == 'Headers') {
    event.req.headers = Object.fromEntries(event.req.headers)
  }
})
@ostapoff ostapoff changed the title useFetch POST with headers and body does not pass headers properly useFetch POST with headers and body does not pass headers properly (node v18) Jul 6, 2022
@danielroe
Copy link
Member

danielroe commented Jul 6, 2022

This wil likely be resolved when we merge unjs/h3#119. We need to provide a normalized headers object or class with a single interface (cc: @pi0).

For now, note that the following are the different ways of reading the headers object.

// internal request via $fetch to /api/call
console.log(event.req.headers.get('cookie'))
// external request direct to /api/call
console.log(event.req.headers.cookie)

@pi0
Copy link
Member

pi0 commented Aug 30, 2022

Node.js req.headers is of type IncomingHttpHeaders (Dict<stirng, string[]>) while Fetch headers are of type Headers. This issue is happening because when using local fetch, headers were being passed as is without conversion. Issue is fixed with [email protected] and available on the latest Nuxt edge (and RC.9+)

We are moving to use more Web-native interfaces in the future in h3 and reduce direct usage of event.{req, res} because they are Node.js APIs and for server direct calls are emulated. While working in normal cases, there are some edge cases like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants