How to get current user agent string from macOS HTMLViewer?

Some sites work well with HTMLViewer but are blocked by user agent string filters. e.g. for WhatsApp the user agent string users by HTMLViewer on macOS is blocked, but the Windows user agent string is allowed.

We can set a custom user agent via HTMLViewer.UserAgent or WKWebViewMBS.customUserAgent and that works around the issue, but does anyone know of a way of reading the default user agent string from the HTMLViewer on macOS? What I’d like to do is read the default user agent string and then set a custom user agent string that is based on it (i.e. using the same OS and WebKit version numbers), rather than hard-coding a WebKit version number that will need to be maintained.

For example, the current user agent string for Safari running on macOS 12.6 on ARM64 is:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15

The default user agent string for a Xojo HTMLViewer on the same machine is:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko)

So it looks like it should be possible to fake the Safari user agent string if it’s possible to read the default user agent string and read the version numbers from it.

Finding the default useragent is easy, so I’m wondering if what you really want, is to find the currently installed webkit version.

If it is the htmlviewer default useragent your looking for, then as far as I know, it’s just an empty string. You can read the property directly:
uaString = myHTMLviewer.useragent
When I run this in my application I just get an empty string. I’m running XOJO 2018r3. So, that may have changed in later versions. For my application though, I set a fake useragent:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:101.0) Gecko/20100101 Firefox/101.0
Once I’ve set it, then it is read back correctly from the useragent property using the above line of code.
Not sure if that’s what you’re asking though.

Thanks for the reply, Robert.

You’re right that what I want to do is find the currently installed WebKit version, but I don’t think HTMLViewer.UserAgent allows me to do that. Instead, it allows you to set and then read back a custom user agent string.

I know that I can hard-code my own user agent string, but what I’m trying to do is find a way of reading the default user agent string so that this doesn’t become something that I have to remember to maintain and update over the years.

You could try executing this instruction, and then parse the result:

HTMLViewer1.LoadURL("https://duckduckgo.com/?t=ffsb&q=what+is+my+useragent&ia=answer")

It’s rather interesting. If you don’t set a useragent, and read the useragent property, then it gives a blank string. But if you execute the above command it will return a useragent string with the webkit version. This seems like a bug. The useragent property should return the same value, but it doesn’t.

Thanks, that’s certainly a creative workaround! I’d prefer to do it locally though, IIRC you can only set the custom user agent string for Xojo’s HTMLViewer in the Open event so delaying that while fetching something from the internet wouldn’t be ideal.

You can use HTMLViewer’s ExecuteJavaScriptSync method to access the Navigator interface, and pass it this: navigator.userAgent

That will return something like this:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko)

Other interesting things that you can get from the navigator object include:
• The platform, via: navigator.platform → ex: MacIntel
• The language, via: navigator.language → en-US
• The browser’s online status, via: navigator.onLine → 1 (true), 0 (false)

I hope that helps.

2 Likes

I tested the javascript code:

window.navigator.userAgent

and it works. I’m using an older version of Xojo that doesn’t have ExecuteJavaScriptSync method to return the value, so I had to resort to the statuschanged hack, but it does work. If you’re using a newer Xojo version, then this should work:

dim usrAgnt as string = htmlviewer1.ExecuteJavaScriptSync("window.navigator.userAgent")

Thanks, Tim: this is perfect, I hadn’t considered trying to do this via JavaScript.