28

I'm using the fetch API in React, and I'm pulling down some data from a JSON endpoint.

As part of my requests, I want to send a custom User-Agent string. Currently, when I inspect my requests, the UA string is:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36

Since I'm pasing in headers with every request, I figured I'd just append User-Agent to the headers object, like it says in various places online:

fetch(url, {
    Accept: 'application/json',
    'Content-Type': 'application/json',
    'User-Agent': 'MY-UA-STRING' // <---
})

But this doesn't work. I have a feeling it's becuase of a bug in the fetch api, as reported here and here and here.

Anyone have a work around on how to pass UA as part of the headers using fetch?

VLAZ
  • 26,331
  • 9
  • 49
  • 67
a53-416
  • 3,585
  • 6
  • 34
  • 44

1 Answers1

38

After some testing, Chrome does indeed have a bug with the User-Agent header.

This is most likely due to the fact that the User-Agent header was on the list of disallowed headers not too long ago (mid 2015).

As this particular header was recently removed from the list of disallowed headers, Firefox (from version 43) will let you change the User-Agent in a fetch call, but Chrome won't.

Here's the Firefox bug, and the Chromium bug

The reason it was disallowed in the first place, was that there's really no good reason to use the User-Agent header to send arbitrary data, it should be used to send the actual User-Agent, and in-browser requests like Fetch of XMLHttpRequest should really have no good reason to spoof the User Agent anyway.

When the bug will be fixed in Chrome is anyones guess, but it is indeed a bug as the list of disallowed headers no longer lists the User-Agent header, and it should change when specified in the options object of Fetch.

As a sidenote, you should generally be creating the headers using the Headers Interface, and include them in the options objects under the headers key

let headers = new Headers({
    "Accept"       : "application/json",
    "Content-Type" : "application/json",
    "User-Agent"   : "MY-UA-STRING"
});

fetch(url, {
    method  : 'GET', 
    headers : headers 
    // ... etc
}).then( ...
adeneo
  • 312,895
  • 29
  • 395
  • 388
  • 4
    Doesn't seem like a bug as this has not changed – Gil SH Aug 17 '20 at 11:37
  • 3
    Re: the "no good reason" paragraph, some [free](https://rxivist.org/docs#Preprints-Details) [API](https://github.com/CrossRef/rest-api-doc#etiquette)s ask that you set the `User-Agent` header to say what your app and contact email is to prevent abuse. I'm not sure this is an appropriate use of `User-Agent` as it was intended -- perhaps that's a mistake on the part of those APIs -- but it is a legitimate reason to set `User-Agent` in fetch on our part. – V. Rubinetti Feb 10 '21 at 19:29
  • 9
    Google Chrome's reluctance to correct this bug may lie in the fact that it would severely impede [browser fingerprinting](https://coveryourtracks.eff.org); which happens to play a significant role in the ad industry. Other headers of privacy concern are `Referer` [sic] and [`Origin`](https://stackoverflow.com/q/42239643/2192488). – Serge Stroobandt Mar 25 '21 at 11:50
  • When my app makes a request to an API, it returns a forbidden 403 error and says my IP address is blocked when using Firefox. However, when I use Chrome, it works perfectly fine. That's why I want to change the User-Agent string so that all browsers use the Chrome User-Agent – Some Guy Jun 23 '23 at 21:54
  • 3
    18.07.2023 - Firefox: can to set custom User-Agent, Chrome: can't – Alexander Jul 18 '23 at 14:02
  • Of course it's because of ads, why wouldn't it be... how did we allow these *sellout* people to make these kind of decisions? – Nora Söderlund Aug 19 '23 at 09:21