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

After upgrade to 1.0 GET request with parameters in the url fail #4999

Closed
jweingarten opened this issue Oct 4, 2022 · 41 comments · Fixed by #5018 or javascript-indonesias/axios#146
Closed

Comments

@jweingarten
Copy link

jweingarten commented Oct 4, 2022

Working request with Axios v1.0.0-alpha.1:

axios.get('https://git.somegit.com/api/v3/search/commits?q=sort:committer-date-desc merge:false repo:org/reponame&per_page=50&page=1

Same request with 1.0.0 fails with a 404. 1.0.0 was promoted today.

When I print the failed response it looks like something is parsed/encoded incorrectly.

   request: <ref *1> ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
       .....
       ..... 
      _headerSent: true,
      socket: [TLSSocket],
      _header: 'GET /api/v3/search/commitsq=sort%3Acommitter-date-desc+merge%3Afalse+repo%3Aorg%2Freponame&per_page=50&page=1 HTTP/1.1\r\n' +
        'Accept: application/vnd.github.cloak-preview+json;application/vnd.github.v3+json\r\n' +
        'User-Agent: axios/1.0.0\r\n' +
        'Accept-Encoding: gzip, deflate, br\r\n' +
        'Host: git.somegit.com\r\n' +
        'Connection: close\r\n' +
        '\r\n',

To me the ? is missing in between commits and q.

When I don't parse the parameters on the URL and use config.params it works with Axios 1.0.0.

    config.params = {
        q: `sort:committer-date-desc merge:false repo:org/reponame`,
        per_page: 50,
        page: 1
    }

The success response then shows this _header:

 _header: 'GET /api/v3/search/commits?q=sort:committer-date-desc+merge:false+repo:org%2Freponame&per_page=50&page=1 HTTP/1.1\r\n' +
      'Accept: application/vnd.github.cloak-preview+json;application/vnd.github.v3+json\r\n' +
      'User-Agent: axios/1.0.0\r\n' +
      'Accept-Encoding: gzip, deflate, br\r\n' +
      'Host: git.somegit.com\r\n' +
      'Connection: close\r\n' +
      '\r\n',

In the working version I do see the ?.

So right now the workaround is either sticking with v1.0.0-alpha.1 or using config.params instead of passing them with the .get call.

@arthurfiorette
Copy link
Contributor

Weird...
Can you provide a reproducible repository so it can be tested out more quickly?

@jweingarten
Copy link
Author

jweingarten commented Oct 5, 2022

Not really ... sorry. I can't give you access to our GIT server to make that GIT api call. I am not sure if its a generic thing with any parameters in the url or just this specific set.
Anything I can provide you with as far as debug print outs where I can remove internal data?

@arthurfiorette
Copy link
Contributor

No need for git acces, just a 2 files repository on github with a nodejs script that calls an express server that throws the same error. Because the above information doesn't seem enough to find a precise solution.

@jweingarten
Copy link
Author

jweingarten commented Oct 5, 2022

How about this?

Curl command for illustration only

For illustration ... a curl command that returns with my personal GIT Access token a list of commits when searching the axios repo. As I said its just for illustration. If you want to execute the curl command you need to update the my_token value in the command.

Request:

curl -v -s -X GET -H "Accept: application/vnd.github.v3+json" -H "Authorization:token my_token" https://api.github.com/search/commits?q=sort:committer-date-desc+merge:false+repo:axios/axios&per_page=50&page=1

Response looks normal as I get a list of commits.

Axios v1.0.0-alpha.1

Steps/Run

  • rm -rf node_modules
  • npm install axios@v1.0.0-alpha.1
  • vi test.js
  • copy/paste this into test.js
const axios = require('axios');

const config = {
    headers: {
        Authorization: 'token my_token',
        Accept: 'application/vnd.github.v3+json'
    }
}

axios.get('https://api.github.com/search/commits?q=sort:committer-date-desc+merge:false+repo:axios/axios&per_page=50&page=1', config).then(function (response) {
    // handle success
    console.log(response);
})
    .catch(function (error) {
        // handle error
        console.log(error);
    })
  • Update my_token with your GIT Access token in above code and save.
  • node test.js

Response looks normal as I get an array of commits back.

Axios v1.0.0

Steps/Run

  • rm -rf node_modules
  • npm install axios
  • use same test.js as above
  • node test.js

Response

AxiosError: Request failed with status code 404
...
...
...
  data: {
      message: 'Not Found',
      documentation_url: 'https://docs.github.com/rest'
    }

@jweingarten
Copy link
Author

Forgot to mention ... I am testing with node --version v14.18.2

@ScriptCamilo
Copy link

ScriptCamilo commented Oct 5, 2022

I am also having the same or similar issue, I was just studying and when I installed the new upgraded version my get call was returning a 404 not found status. I'm using node --version v16.17.0. My study code was something like this:

const { get } = require('axios');
const URL = 'https://swapi.dev/api/people';

async function getPeople(name) {
  const url = `${URL}/?search=${name}&format=json`;
  console.time('call-api');
  const response = await get(url);
  console.timeEnd('call-api');

  console.log(response.data.results);
  return response.data;
}

getPeople('r2-d2');

module.exports = {
  getPeople,
};

It works fine on the "axios": "^0.27.2"

@jasonsaayman
Copy link
Member

This might be an oversight but in v1 we have been a lot stricter with our URL parsing. The URL is for your URL free of any query params. Thus we have params as part of the config.

If you use a URL like this http://test.example.com?test=1 we will be stripping out the ?. Please use the params to set query params.

@evanhurd
Copy link

evanhurd commented Oct 5, 2022

That's ridiculous. I love axios and it's my goto client in node but this breaking change hurts the ergonomics of the library.

@janitza-mage
Copy link

Please use the params to set query params.

I have the same problem as the original poster.

Does this mean that, to send a request to an URL from elsewhere that may contain a query string, I have to detect the question mark, split the URL manually and put the querystring into the params? This probably also means that I should be using URLSearchParams to avoid writing a querystring parser myself, right?

@ddolcimascolo
Copy link

Same here, we're going to refactor but there is no mention of this in the breaking changes

@ddolcimascolo
Copy link

Fun fact, axios.getUri still work... This honestly look like ther's something weird.

Can we get a word from Axios maintainers ?

@ddolcimascolo
Copy link

ddolcimascolo commented Oct 5, 2022

For those wondering, or too lazy to refactor everything, or using Axios to fetch full URLs they don't manage (our use case: we fetch a RSS feed containing links to items and the item URL might contain query params, it's an opaque string for us) I resorted to using this interceptor:

instance.interceptors.request.use((req) => {
  const url = new URL(axios.getUri(req)), // getUri will build the final URI, merging defaults
        params = new URLSearchParams(url.searchParams);

  url.search = '';

  req.url = url.href; // The URL without query params
  req.params = params; // The merged query params from defaults + request

  return req;
});

In my context, I'm paying the extra CPU cycles for the useless interceptor. I'm hoping for Axios to reintroduce previous behavior

@abrkn
Copy link

abrkn commented Oct 5, 2022

Thanks, @ddolcimascolo. Is the order of the params deterministic? I'm using axios for an API that signs the search params and appends that as the last search param:

GET /some-api/secret?f1=a&f2=b&f3=c&signature=<sig>

Where <sig> is determined by signing GET/some-api/secret?f1=a&f2=b&f3=c

@abrkn
Copy link

abrkn commented Oct 5, 2022

This is a very unfortunate breaking change which I hope the maintainers will reconsider.

@ddolcimascolo
Copy link

Thanks, @ddolcimascolo. Is the order of the params deterministic? I'm using axios for an API that signs the search params and appends that as the last search param:

GET /some-api/secret?f1=a&f2=b&f3=c&signature=<sig>

Where <sig> is determined by signing GET/some-api/secret?f1=a&f2=b&f3=c

I'd say yes

@dnohr
Copy link

dnohr commented Oct 5, 2022

I can confirm this error as well after upgrading to v1.0.

Simple scripts are failing, so I had to roll back to v0.27.2.

Hope it's some simple issue which can easily be fixed.

Thanks for working on the project!

@SteveW94
Copy link

SteveW94 commented Oct 5, 2022

I can also confirm these errors as lots of our get requests are failing now and we had to rollback.

@Hiryus
Copy link

Hiryus commented Oct 5, 2022

Same here.
Tests are broken on v1.0.0 (node 16) because query parameters are no longer working.

Since most APIs, including nodejs include the search parameters in the URL object, this change is miss-leading in my opinion.
Especially since there is no warning in the readme about it.

Also, it is very strange to remove the ? character but not the actual parameters behind it if the url configuration param actually contains a query string... this is asking for trouble, I think.

@ddolcimascolo
Copy link

@jasonsaayman @mzabriskie @nickuraltsev It's clear now that this goes beyond a simple whoopsie 😅

Do you agree on fixing this? If so, I'm willing to work on a PR if this is of any help.

Cheers,
David

@SteveW94
Copy link

SteveW94 commented Oct 5, 2022

@ddolcimascolo I would be very happy if you would do so :)

@Jannchie
Copy link

Jannchie commented Oct 5, 2022

This is definitely a bug. this disruptive change is not mentioned anywhere.

@dtinth
Copy link

dtinth commented Oct 5, 2022

Came here from this StackOverflow question.

The docs still says that ? can be used in URL string, and using params config is optional.

image

To resolve the discrepancy, either the library can be updated to support query params in URL strings (like in v0), or the docs can be updated to match the current v1 behavior.

@SteveW94
Copy link

SteveW94 commented Oct 5, 2022

As I see no good reason for the New behaviour I would recommend to restore the one from v0 🙈

@SSANSH
Copy link

SSANSH commented Oct 5, 2022

+1

@jweingarten jweingarten changed the title After upgrade to 1.0 GET request fails After upgrade to 1.0 GET request with parameters in the url fail Oct 5, 2022
@sfalpha
Copy link

sfalpha commented Oct 5, 2022

Path including Query String is considered URL (URI) in HTTP semantics

https://www.rfc-editor.org/rfc/rfc9110.html
https://www.rfc-editor.org/rfc/rfc3986.html#page-16

This changes break any application that accept URL as user input and pass directly as URL to axios.get(), post() and others.
Axios should support URL scheme according to HTTP semantics to conform with specifications and better user experience.

In case user supply query_params it should append to URL with & or ? as neccessary.

@jcurlier
Copy link

jcurlier commented Oct 5, 2022

+1

@DigitalBrainJS
Copy link
Collaborator

@jasonsaayman seems like PR #4852 should be reverted for now. Axios should definitely be able to parse params from a query string. Currently, these changes do more harm than good, since the problem they solve is not critical, but only potentially possible and has existed for years. This should be carefully considered from all points of view before such incompatibilities are introduced. Another, more thoughtful solution should be found.

@typeofweb
Copy link

Clearly, this is a bug in Axios. new URL(…) has no problem parsing query params:

new URL('https://api.example.com/path?bug=axios')
URL {
  href: 'https://api.example.com/path?bug=axios',
  origin: 'https://api.example.com',
  protocol: 'https:',
  username: '',
  password: '',
  host: 'api.example.com',
  hostname: 'api.example.com',
  port: '',
  pathname: '/path',
  search: '?bug=axios',
  searchParams: URLSearchParams { 'bug' => 'axios' },
  hash: ''
}

DigitalBrainJS added a commit to DigitalBrainJS/axios that referenced this issue Oct 5, 2022
jasonsaayman pushed a commit that referenced this issue Oct 5, 2022
* Fixes #4999;

* Added regression test;
@jasonsaayman
Copy link
Member

Fixed with #5018

@jasonsaayman
Copy link
Member

Sorry about that, something that I should have picked up, I will try to be a bit more strict on changes which are to largely incompatible.

@ddolcimascolo
Copy link

Thx for fixing @jasonsaayman 👍

@jasonsaayman
Copy link
Member

No probs but credit goes to @DigitalBrainJS. Sorry for all the problems this caused. Please can anyone interested watch our releases as we need many more testers on pre-releases, I can only do so much.

@gdelory
Copy link

gdelory commented Oct 6, 2022

Any idea on the date of the next release? Just to know if we rollback to 0.x or wait for the new release :)

@jasonsaayman
Copy link
Member

Releaseing now

@philBrown
Copy link

@jasonsaayman Why was the fix shipped in a minor release and not a patch? I would have expected v1.0.1

Won't this remain broken for anyone using approximate equivalent version?

"axios": "~1.0.0"

@abrkn
Copy link

abrkn commented Oct 7, 2022

Thanks for fixing this issue so quickly, @jasonsaayman!

@janitza-mage
Copy link

Can confirm that it works for me. That was fast! Thanks a lot.

@jasonsaayman
Copy link
Member

Im bumping as minor cause its not the only change

@philBrown
Copy link

@jasonsaayman could you please roll out a v1.0.1 patch release with the URL query param fix then?

That or pull v1.0.0 entirely. As mentioned already, anyone using ~1.0.0 won't get the fix

@mgiraldo
Copy link

had this same issue. reverting to 0.27.2 fixed it.

this is how a working call looks for me (v0.27.2):

image

this is what a broken call looks for me (v1.3.4) with no code changes, just upgrading the package:

image

@rangelanino
Copy link

Same issue. Though I think its partly because our app uses WebPack and not Rollup.

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