A request parameter error occurred in Edge Functions, which was normal before

Edge Function:

export default req => new Response(new URL(req.url).search.substring(1))
export const config = { path: "/url-edge" }

Example:

https://testfunc.netlify.app/url-edge?p1=a%3D1%26b%3D2&p2=a%3D3%26b%3D4

Normal before p1=a%3D1%26b%3D2&p2=a%3D3%26b%3D4
Parsed:

console.log(...new URLSearchParams('p1=a%3D1%26b%3D2&p2=a%3D3%26b%3D4'))
// ['p1', 'a=1&b=2'] ['p2', 'a=3&b=4']

Now it becomes p1=a=1&b=2&p2=a=3&b=4
Parsed:

console.log(...new URLSearchParams('p1=a=1&b=2&p2=a=3&b=4'))
// ['p1', 'a=1'] ['b', '2'] ['p2', 'a=3'] ['b', '4']

My guess is that the employee wanted to fix this problem but made a mistake.

You will see the same results using Developer Tools in Firefox or Opera so this (IMHO) is nothing to do with Edge Functions but URLSearchParams itself.

Why are you using encoded strings in the first place?

I mean https://testfunc.netlify.app/url-edge?p1=a%3D1%26b%3D2&p2=a%3D3%26b%3D4 Edge Function should receive ['p1', 'a=1&b=2'] ['p2', 'a=3&b=4'], but actually receives ['p1', 'a=1'] [' b', '2'] ['p2', 'a=3'] ['b', '4']

Another example: https://testfunc.netlify.app/url-edge?api=https%3A%2F%2Fhttpbin.org%2Fget%3Fname%3Djohn%26gender%3D1%26age%3D22

The parameter api is https://httpbin.org/get?name=john&gender=1&age=22, but it becomes https://httpbin.org/get?name=john in Edge Functions.

Why are you using new URL(req.url).search.substring(1)? Are you parsing the value of this? Why aren’t you using new URL(req.url).searchParams?

Either this is a very unique problem for a very unique use case (as previously mentioned) or your usage of Web APIs is back-to-front, upside-down and inside-out and without seeing the code and understanding what you are doing with it, it is near impossible to provide a solution.

I tested it, same result

export default req => {
  const params = new URL(req.url).searchParams
  for (const [key, value] of params) {
    console.log(key, value)
  }
  return new Response('ok')
}
export const config = { path: "/log-params" }
https://testfunc.netlify.app/log-params?p1=a%3D1%26b%3D2&p2=a%3D3%26b%3D4

info   [logParams] p1 a=1
info   [logParams] b 2
info   [logParams] p2 a=3
info   [logParams] b 4
https://testfunc.netlify.app/log-params?api=https%3A%2F%2Fhttpbin.org%2Fget%3Fname%3Djohn%26gender%3D1%26age%3D22

info   [logParams] api https://httpbin.org/get?name=john
info   [logParams] gender 1
info   [logParams] age 22

When I test your code locally (ntl dev using localhost:8888 in place of testfunc.netlify.app)

outputs

[log-params] p1 a=1&b=2
[log-params] p2 a=3&b=4

and

outputs

[log-params] api https://httpbin.org/get?name=john&gender=1&age=22

Do you get the same (I assume correct) results when testing locally and different (I assume incorrect) results when deployed to Netlify? Or do you get the same results either way?

Yes, it is correct when netlify dev locally, but not correct when deployed to Netlify.

Hey folks, thanks for reporting this issue! Your hunch was right, this was related to a fix for Don't reorder request parameters in Edge Functions. I’ve rolled back the fix because it was causing some minor issues, and your argument also makes sense to me. The main point in RFC3986 that we need to adhere to is this:

Percent-encoding a reserved character, or decoding a percent-encoded octet that corresponds to a reserved character, will change how the URI is interpreted by most applications. Thus, characters in the reserved set are protected from normalization and are therefore safe to be used by scheme-specific and producer-specific algorithms for delimiting data subcomponents within a URI.
~ § 2.2 Reserved Characters

You should be seeing the same behaviour across production and netlify dev again on this now.