Coder Social home page Coder Social logo

Comments (31)

IvoPereira avatar IvoPereira commented on August 12, 2024 4

Hi again @microcipcip!

I have been trying to reproduce such an issue myself as I've been getting this the past week.

My use case is the following:

  1. I initialize an Axios instance as a plugin, setting up some defaults like Base URL and some headers. I do setup request and response interceptors as well. Request interceptor does set withCredentials to true. The response interceptor is described in point 4)
  2. I want to fill the initial Vuex state of the app using nuxtServerInit
  3. In nuxtServerInit I dispatch an action that "bootstraps" the state, making an Axios request (using the already setup instance) to an endpoint that sets cookies
  4. This request goes through a response interceptor that grabs the set cookies and (should) set them universally (server-side and client-side) using cookie-universal-nuxt

Pasting the source-code that does this for quick reference:

axios.interceptors.response.use(
  (res) => {
    const parsedSetCookies = SetCookieParser.parse(res)

    console.info('Logging PARSED SET COOKIES...', parsedSetCookies)

    parsedSetCookies.forEach((cookie) => {
      // Have an object with cookie options only
      const cookieOptions = { ...cookie }
      delete cookieOptions.name
      delete cookieOptions.value

      console.info(
        'Now setting cookies: ',
        cookie.name,
        cookie.value,
        cookieOptions
      )
      cookieManager.set(cookie.name, cookie.value, cookieOptions)
    })

    return res
  },
  function (error) {
    return Promise.reject(error)
  }
)

Keep in mind that cookieManager is app.$cookiz (as setup by the recommended option with an alias).

  1. Cookies are successfully set in the request call. However, if I end up refreshing the page where this first call is done, I end up getting:
 WARN  Cannot set headers after they are sent to the client                                       09:29:53

  at ServerResponse.setHeader (_http_outgoing.js:526:11)
  at p (node_modules/cookie-universal/dist/cookie-universal-common.js:1:1399)
  at Object.set (node_modules/cookie-universal/dist/cookie-universal-common.js:1:1836)
  at server.js:4238:23
  at Array.forEach (<anonymous>)
  at server.js:4231:24
  at processTicksAndRejections (internal/process/task_queues.js:97:5)
  at async Object.bootstrap (server.js:4247:12)
  at async Store.bootstrap (server.js:4302:19)
  1. I am able to get it to work again when I restart the Nuxt dev environment, so I suppose this is somehow related to the way cookies are being stored/accessed in the server-side of Nuxt.

I have setup a demo repo of the issue and how you can reproduce it:
https://github.com/IvoPereira/cookie-universal-nuxt-demo-issue

Clone the directory locally, npm install and open two terminal instances and, in each one, in the project root:

  1. node server.js - To run the local server that will set cookies on the server
  2. npm run dev - To run Nuxt development environemnt

Watch closely the logs of the Nuxt server environment and when refreshing the app the second time you will see it happening.

I might be using something incorrectly but I am not exactly sure what so would appreciate any help on this.

A small note for anyone getting here through Google: If your headers are not even sent at once to the next Axios request, you might be having this issue.

from cookie-universal.

microcipcip avatar microcipcip commented on August 12, 2024 2

I thought that was the issue as well, but as the interceptor is for an Axios response, I understand the response was already sent for the Axios request, but I don't see how it was already sent for the Nuxt server-side (does this make sense)?

Yeah I understand what you mean, the problem is I don't fully understand how Nuxt handles things on his end, I'll have to investigate. If it was a regular express server I would understand the problem more easily. I'll get back to you when I find a solution.

from cookie-universal.

vuejsstudy avatar vuejsstudy commented on August 12, 2024 1

Same issue here... In my case I'm setting cookie after mutate a vuex store.

`
UPDATE_TOKEN(state, object) {
state.token = object.token
this.$cookies.set("token", object.token)
}

Cannot set headers after they are sent to the client 09:26:03

at ServerResponse.setHeader (_http_outgoing.js:526:11)
at p (node_modules\cookie-universal\dist\cookie-universal-common.js:1:1399)
at Object.set (node_modules\cookie-universal\dist\cookie-universal-common.js:1:1836)
at Store.UPDATE_USER (server.js:13022:19)
at wrappedMutationHandler (node_modules\vuex\dist\vuex.common.js:842:13)
at commitIterator (node_modules\vuex\dist\vuex.common.js:464:7)
at Array.forEach ()
at node_modules\vuex\dist\vuex.common.js:463:11
at Store._withCommit (node_modules\vuex\dist\vuex.common.js:622:3)
at Store.commit (node_modules\vuex\dist\vuex.common.js:462:8)
at Store.boundCommit [as commit] (node_modules\vuex\dist\vuex.common.js:407:19)
at VueComponent.userInfo (server.js:4231:19)
at runMicrotasks ()
ยป Updated store\index.js
`

from cookie-universal.

microcipcip avatar microcipcip commented on August 12, 2024 1

@IvoPereira this is awesome, I was spending an hour just now to try to reproduce this error.

I think I need to change the documentation, a cookie cannot be set after the response is sent to the client. So what is happening is that in axios.interceptors.response.use the response is already sent, you can't change it anymore. It is a problem similar to this.

So it is equivalent to doing this:

app.post('/test', (req, res) => {
    res.status(400).json({
      status: 'succes',
      data: req.body,
    });

  // This fails because you have already sent the request
   res.setHeader('Set-Cookie', someSerializedCookieHere)
});

from cookie-universal.

microcipcip avatar microcipcip commented on August 12, 2024

If you show me the code I can help you debug it, but this is not related to this cookie library. You can't set headers after they have been sent.

from cookie-universal.

september-evgeny avatar september-evgeny commented on August 12, 2024
  nuxtServerInit({ commit, dispatch, getters }, { app, req }) {
    app.$cookies.set('test', 'hoho')
  }
 ERROR  Cannot set headers after they are sent to the client                                                                                                                                                                 14:34:08
  at ServerResponse.setHeader (_http_outgoing.js:485:11)
  at p (node_modules/cookie-universal/dist/cookie-universal-common.js:1:1399)
  at Object.set (node_modules/cookie-universal/dist/cookie-universal-common.js:1:1836)
  at Store.nuxtServerInit (store/index.js:6:0)
  at Array.wrappedActionHandler (node_modules/vuex/dist/vuex.common.js:794:23)
  at Store.dispatch (node_modules/vuex/dist/vuex.common.js:459:15)
  at Store.boundDispatch [as dispatch] (node_modules/vuex/dist/vuex.common.js:349:21)
  at module.exports../.nuxt/server.js.__webpack_exports__.default (.nuxt/server.js:133:0)

Nuxt.js @ v2.13.1
I tried it differently, it does not work. And this is not only with me.

from cookie-universal.

microcipcip avatar microcipcip commented on August 12, 2024

Are you in universal mode or static mode? In static mode the headers are not available

from cookie-universal.

september-evgeny avatar september-evgeny commented on August 12, 2024

universal

from cookie-universal.

microcipcip avatar microcipcip commented on August 12, 2024

Ok, thanks, then I'll try to reproduce the issue and see if I get the same result.

from cookie-universal.

williamweckl avatar williamweckl commented on August 12, 2024

Same issue here... In my case I'm setting cookie after mutate a vuex store.

 ERROR  Cannot set headers after they are sent to the client                                                                                                         22:15:04

  at ServerResponse.setHeader (_http_outgoing.js:518:11)
  at p (node_modules/cookie-universal/dist/cookie-universal-common.js:1:1399)
  at Object.set (node_modules/cookie-universal/dist/cookie-universal-common.js:1:1836)
  at Store.setSelectedPlatform (store/modalities.js:1:0)
  at wrappedMutationHandler (node_modules/vuex/dist/vuex.common.js:842:13)
  at commitIterator (node_modules/vuex/dist/vuex.common.js:464:7)
  at Array.forEach (<anonymous>)
  at node_modules/vuex/dist/vuex.common.js:463:11
  at Store._withCommit (node_modules/vuex/dist/vuex.common.js:622:3)
  at Store.commit (node_modules/vuex/dist/vuex.common.js:462:8)
  at Store.boundCommit [as commit] (node_modules/vuex/dist/vuex.common.js:407:19)
  at module.exports../plugins/modalities.js.__webpack_exports__.default (plugins/modalities.js:1:0)
  at runMicrotasks (<anonymous>)
  at processTicksAndRejections (internal/process/task_queues.js:97:5)
  at async createApp (.nuxt/index.js:221:0)
  at async module.exports../.nuxt/server.js.__webpack_exports__.default (.nuxt/server.js:81:0)

My store code:

export const state = () => ({
  modalities: [],
  selected: null,
  selectedPlatform: null,
})

export const mutations = {
  setModalities(state, modalities) {
    state.modalities = modalities
  },

  setSelectedPlatform(state, selected) {
    state.selectedPlatform = selected
    this.$cookies.set('stores/modalities/selected-platform', selected)
  },
}

This error is really hard to reproduce, it happens sometimes and I don't know exactly how to reproduce. Happened to me only once at development, but Sentry is raising some issues.

from cookie-universal.

acibilous avatar acibilous commented on August 12, 2024

any updates?

from cookie-universal.

microcipcip avatar microcipcip commented on August 12, 2024

Sorry I forgot to check, I'll set some time to have a look at this.

from cookie-universal.

sonnh58 avatar sonnh58 commented on August 12, 2024

same issue

from cookie-universal.

microcipcip avatar microcipcip commented on August 12, 2024

Hey guys, where are you getting the error? In nuxtServerInit? The error you're getting is from the node server, not from this library. What is happening is that the server is returning the request, and you are trying to set the cookie after that the request is already sent to the client. Maybe this info will help you debug your code, or show me how you are calling your vuex actions so to help me understand why it fails.

from cookie-universal.

stale avatar stale commented on August 12, 2024

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.

from cookie-universal.

lql25 avatar lql25 commented on August 12, 2024

same question

from cookie-universal.

IvoPereira avatar IvoPereira commented on August 12, 2024

Awesome, glad it helped.

I thought that was the issue as well, but as the interceptor is for an Axios response, I understand the response was already sent for the Axios request, but I don't see how it was already sent for the Nuxt server-side (does this make sense)?

How would you approach this need of wanting to grab the Set-Cookies that come in a response, have them universally (Nuxt client and server) and be able to send them as Cookies in the next Axios request?

from cookie-universal.

IvoPereira avatar IvoPereira commented on August 12, 2024

Hi @microcipcip,

I have done some follow-up investigation on this and from what I was able to observe, I am concluding that this might be some edge case with handling setHeader inside an Axios interceptor.

I've been doing some follow-up experiments in the same repo but in a separate branch (in case you want to check):
https://github.com/IvoPereira/cookie-universal-nuxt-demo-issue/tree/debug/axios-interceptors

I have reduced the dependencies in the demo repo, and now I have it working or not depending on a flag I pass (useInterceptors true/false),

The steps are basically the same, but so that you can see a working behaviour you need to set useInterceptors to false, and to see the non-working behaviour you need to set it as true.

In the first SSR request both of them work, however when you make a page refresh, the one with Interceptors will start showing "Cannot set headers after they are sent to the client".

It looks like SSR does not wait for response interceptor to arrive before ending SSR content sending.

Will keep trying if I can discover something else.

Let me know if this helps or if it any of these ideas need some cleanup, as I've been looking into this for a few hours.

from cookie-universal.

microcipcip avatar microcipcip commented on August 12, 2024

Thank you very much @IvoPereira for dedicating your time in investigating this issue. I haven't got the time to see it yet but your repo will be a good start for debugging and hopefully fix it.

from cookie-universal.

stale avatar stale commented on August 12, 2024

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.

from cookie-universal.

jonalxh avatar jonalxh commented on August 12, 2024

Hi. I'm facing this issue but I don't know how to solve it, I need to set a Content-Language header after the user changes the language, I'm trying to handle it with the cookies, but my console is full of Cannot set headers after they are sent to the client messages.

$axios.interceptors.request.use(async (config) => {
		let lang = await app.$cookies.get("userLang")

		if (lang) {
			config.headers.common["Accept-Language"] = lang
			config.headers.common["Content-Language"] = lang
		}
		return config
	})

How can I solve it?

from cookie-universal.

microcipcip avatar microcipcip commented on August 12, 2024

@jonalxh cookies.get is not a promise, is sync code. Can you try this instead?

$axios.interceptors.request.use(config => {
		const lang = app.$cookies.get("userLang")
		if (lang) {
			config.headers.common["Accept-Language"] = lang
			config.headers.common["Content-Language"] = lang
		}
		return config
	})

from cookie-universal.

jonalxh avatar jonalxh commented on August 12, 2024

@jonalxh cookies.get is not a promise, is sync code. Can you try this instead?

$axios.interceptors.request.use(config => {
		const lang = app.$cookies.get("userLang")
		if (lang) {
			config.headers.common["Accept-Language"] = lang
			config.headers.common["Content-Language"] = lang
		}
		return config
	})

I used to have the code in that way, but the error was visible is same way.

from cookie-universal.

microcipcip avatar microcipcip commented on August 12, 2024

@jonalxh if you run this code, do you still get the Cannot set headers after they are sent to the client message?

$axios.interceptors.request.use(config => {
  config.headers.common["Accept-Language"] = 'someText'
  config.headers.common["Content-Language"] = 'someText'
  return config
})

from cookie-universal.

stale avatar stale commented on August 12, 2024

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.

from cookie-universal.

imfsilva avatar imfsilva commented on August 12, 2024

Any news? I'm facing the same problem

nuxt_1 | ERROR Cannot set headers after they are sent to the client
nuxt_1 |
nuxt_1 | at ServerResponse.setHeader (_http_outgoing.js:526:11)
nuxt_1 | at p (node_modules/cookie-universal/dist/cookie-universal-common.js:1:1399)
nuxt_1 | at Object.set (node_modules/cookie-universal/dist/cookie-universal-common.js:1:1836)
nuxt_1 | at Object.remove (node_modules/cookie-universal/dist/cookie-universal-common.js:1:2776)
nuxt_1 | at server.js:12632:26
nuxt_1 | at processTicksAndRejections (internal/process/task_queues.js:97:5)
nuxt_1 | at async Store.getList (server.js:2992:19)

from cookie-universal.

YangMaoxiang avatar YangMaoxiang commented on August 12, 2024

@jonalxh if you run this code, do you still get the Cannot set headers after they are sent to the client message?

$axios.interceptors.request.use(config => {
  config.headers.common["Accept-Language"] = 'someText'
  config.headers.common["Content-Language"] = 'someText'
  return config
})

Is there a solution to this problem please? We also encountered the same problem.

from cookie-universal.

jonalxh avatar jonalxh commented on August 12, 2024

In my case I tried the @microcipcip and it didn't work, it is still throwing the same error.

from cookie-universal.

microcipcip avatar microcipcip commented on August 12, 2024

I tried to contact the maintainers of the Axios plugin to understand how it interacts with the server, but could not manage to go through it.

from cookie-universal.

microcipcip avatar microcipcip commented on August 12, 2024

Maybe try to use the new useFetch API?

from cookie-universal.

Pouria-Meftahi avatar Pouria-Meftahi commented on August 12, 2024

in my case i find the problem is the dif with package-lock.json version

from cookie-universal.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.