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

how to set global paramsSerializer? #5217

Open
zhoufanglu opened this issue Nov 1, 2022 · 16 comments
Open

how to set global paramsSerializer? #5217

zhoufanglu opened this issue Nov 1, 2022 · 16 comments

Comments

@zhoufanglu
Copy link

zhoufanglu commented Nov 1, 2022

Describe the bug

"axios": "^1.1.3",
how to set global paramsSerializer?

To Reproduce

none

Code snippet

  • config
const service = axios.create({
  baseURL: `${import.meta.env.VITE_APP_WEB_URL}/`,
  timeout: 10000,
  // `paramsSerializer`是可选方法,主要用于序列化`params`
  paramsSerializer: (params: any) => {
    console.log(11, params)
    return qs.stringify(params, { arrayFormat: 'repeat' }) // 形式: ids=1&ids=2&ids=3
  }
} as AxiosRequestConfig)
  • use
testB(params: any) {
    return axios.get('/testB', params)
  },

Expected behavior

qs success

happend

image

@reatiny
Copy link

reatiny commented Nov 1, 2022

I share the same problem when I use paramsSerializer.
311667318320_ pic
321667318354_ pic

@luisdeka
Copy link

luisdeka commented Nov 1, 2022

same problem

@philBrown
Copy link

Duplicate of #5206

@reatiny
Copy link

reatiny commented Nov 3, 2022

paramsSerializer: {
// encode: (params) => qs.stringify(params, { arrayFormat: 'repeat' })
indexes: null
}

@ghost
Copy link

ghost commented Nov 3, 2022

https://github.com/axios/axios/blob/v1.x/lib/helpers/buildURL.js#L41

paramsSerializer: {
  serialize(params: Record<string, unknown>): string => {
    // do your old paramsSerializer logic here
  }
}

from the docs:

New-old ParamsSerializer support added by @DigitalBrainJS in #5113
Docs added by @ChronosMasterOfAllTime in #5108 (plus ignore nullish values)

image

@zhoufanglu
Copy link
Author

zhoufanglu commented Nov 9, 2022

  • call
    image

  • config

const service = axios.create({
  baseURL: `${import.meta.env.VITE_APP_WEB_URL}/`,
  timeout: 10000,
  paramsSerializer: {
    encode: (params) => {
      return qs.stringify(params, { arrayFormat: 'repeat' })
    }
    // serialize: (params, options)
    // indexes: null
  }
} as AxiosRequestConfig)
  • no params in url
    image

@GitHubJiKe
Copy link

same issue
version: 0.24.0
i use qs.stringify in a request interceptor, but failed, anybody knows how to fix?

@cableray
Copy link

cableray commented Nov 22, 2022

This is a breaking change, and it was introduced in a patch level version... Seems like a bad idea, and it seems like it is possible to support the old function style version... Would that be an acceptable feature request, maybe with a deprecation warning?

@ChronosMasterOfAllTime
Copy link
Contributor

ChronosMasterOfAllTime commented Nov 22, 2022

  • call
    image

  • config

const service = axios.create({
  baseURL: `${import.meta.env.VITE_APP_WEB_URL}/`,
  timeout: 10000,
  paramsSerializer: {
    encode: (params) => {
      return qs.stringify(params, { arrayFormat: 'repeat' })
    }
    // serialize: (params, options)
    // indexes: null
  }
} as AxiosRequestConfig)
  • no params in url
    image

Change encode to serialize. The encode function takes an iterative approach of passing each individual key then value. Serialize function will pass the entire params object.

For example

encode will be called many times in the following order with the following param per call:

"name"
"abc"
"age"
"18"
"list"
[1,2,3]

serialize on the other hand will be called with your entire params object like you have in the jsdoc.

@ChronosMasterOfAllTime
Copy link
Contributor

This is a breaking change, and it was introduced in a patch level version... Seems like a bad idea, and it seems like it is possible to support the old function style version... Would that be an acceptable feature request?

The serialize function inside the paramsSerializer object supports the old methodology.

I honestly don't know why this was changed (maybe to use the same form data logic?). It seems like the new way should have been behind some sort of feature flag.

@zhoufanglu zhoufanglu changed the title hot to set global paramsSerializer? how to set global paramsSerializer? Nov 25, 2022
@lebronxie
Copy link

 //  you should check  axios version in package.json   
 //  axios version >1.X   paramsSerializer must be Object   
 // The following is the npm axios document
  paramsSerializer: {
    encode?: (param: string): string => { /* Do custom ops here and return transformed string */ }, // custom encoder function; sends Key/Values in an iterative fashion
    serialize?: (params: Record<string, any>, options?: ParamsSerializerOptions ), // mimic pre 1.x behavior and send entire params object to a custom serializer func. Allows consumer to control how params are serialized.
    indexes: false // array indexes format (null - no brackets, false (default) - empty brackets, true - brackets with indexes)
  },

@Spirit04eK
Copy link

Axios.interceptors.request.use(config => {
  config.paramsSerializer = {
    serialize: Qs.stringify(params, {
      encode: true,
    }),
  };
  return config;
});

@vopecula
Copy link

@Spirit04eK Thanks, this was my problem. I tried config.paramsSerializer.serialize, but it does not exists here. I tought that it will be always there, but config.paramsSerializer is empty here.

@anna-holmes
Copy link

I was able to set paramsSerializer when creating my axios instance and see it apply correctly to requests --

let instance = axios.create({
  paramsSerializer: (params) => Qs.stringify(params, { arrayFormat: 'brackets' })
});

Using axios version 1.6.0.

Looks like it was fixed here: #5633

@GitHubJiKe
Copy link

I set global paramsSerializer by code as below, hope can help u.

let instance = axios.create({...});
instance.defaults.paramsSerializer = params => qs.stringify(params, { arrayFormat: 'repeat' });

@samuelpucat
Copy link

I wanted to set it up without external library and this works so far:

paramsSerializer: {
    encode: (value, defaultEncoder) => {
        return defaultEncoder(value);
    },
},

This is the defaultEncoder function (axios@1.6.8):

/**
 * It encodes a string by replacing all characters that are not in the unreserved set with
 * their percent-encoded equivalents
 *
 * @param {string} str - The string to encode.
 *
 * @returns {string} The encoded string.
 */
function encode(str) {
  const charMap = {
    '!': '%21',
    "'": '%27',
    '(': '%28',
    ')': '%29',
    '~': '%7E',
    '%20': '+',
    '%00': '\x00'
  };
  return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {
    return charMap[match];
  });
}

defaultEncoder escapes all characters except A–Z a–z 0–9 - _ . ! ~ * ' ( ), then replaces
'!' for '%21',
"'" for '%27',
'(' for '%28',
')' for '%29',
'~' for '%7E',
'%20' for '+',
'%00' for '\x00'

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

No branches or pull requests