Cypress API集成测试中如何修改QueryString多值参数的序列化行为?(无法使用cy.intercept())
Hey there, I've run into this exact issue before with Cypress's default query string serialization for arrays. Here are a few solid workarounds that don't involve cy.intercept():
1. Manually Construct the Full URL
The simplest approach is to bypass Cypress's automatic serialization entirely by building the URL with your desired query parameters directly:
cy.request({ method: 'GET', url: '/exampleapi.com?type=1&type=2' });
This works because you're explicitly defining the query string, so Cypress won't modify it. It's ideal for one-off requests where you don't need dynamic parameters.
2. Use qsOptions to Configure Array Serialization
Cypress uses the qs library under the hood, which supports different array formatting options. You can set arrayFormat: 'repeat' either per-request or globally to get the duplicate key format you need.
Per-Request Configuration:
cy.request({ method: 'GET', url: '/exampleapi.com', qs: { type: [1, 2] }, qsOptions: { arrayFormat: 'repeat' } });
This tells Cypress to serialize the type array as type=1&type=2 instead of the default type[]=1&type[]=2.
Global Configuration (for all requests):
Add this to your cypress.config.js file to apply the setting across all tests:
const { defineConfig } = require('cypress'); module.exports = defineConfig({ e2e: { setupNodeEvents(on, config) { // Override default qs options globally config.qsOptions = { arrayFormat: 'repeat' }; return config; }, }, });
Now any cy.request with an array in qs will use the duplicate key format automatically.
3. Hook into request:before:send to Modify the Request
If you need more control (e.g., handling multiple array parameters dynamically), you can use Cypress's request:before:send event to adjust the URL before it's sent:
// Add this in cypress.config.js setupNodeEvents on('request:before:send', (req) => { const queryParams = []; Object.entries(req.qs).forEach(([key, value]) => { if (Array.isArray(value)) { // Add each array item as a separate key-value pair value.forEach(item => { queryParams.push(`${encodeURIComponent(key)}=${encodeURIComponent(item)}`); }); } else { // Handle non-array parameters normally queryParams.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`); } }); // Rebuild the URL with the custom query string const queryString = queryParams.join('&'); req.url = req.url.split('?')[0] + (queryString ? `?${queryString}` : ''); // Clear the qs to prevent default serialization req.qs = {}; });
This will iterate through all your query parameters, turn arrays into duplicate keys, and reconstruct the URL accordingly. Perfect if you have multiple array parameters across many requests.
Each of these methods avoids using cy.intercept() and should get your request working as expected. Pick the one that fits your use case best!
内容的提问来源于stack exchange,提问作者Juan Rabadan

