Limitations when using JXA

JXA does not run in the browser. So all global objects available there don’t exist in JXA scripts. This concerns window (with methods like alert()), document (with all DOM methods like getElementById()) and navigator.

Most importantly, you cannot use XHR calls from JXA scripts (XMLHttpRequest(), fetch() etc.). Consequently, there’s no (easy) way to work with the DOM of a web document.

You can, however, download a web document with (for example) curl and then access its content with the methods for strings and regular expressions. Alternatively, you could use the Objective-C bridge:

const urlStr = "";
const htmlStr = getHTMLSource(urlStr);

function getHTMLSource(URL) {  
  const nsURL     = $.NSURL.URLWithString(URL);
  const nsHTML     = $.NSData.dataWithContentsOfURL(nsURL);
  const nsHTMLStr = $.NSString.alloc.initWithDataEncoding(
    nsHTML,  $.NSUTF8StringEncoding);

  return ObjC.unwrap(nsHTMLStr);

This code was originally posted in the JXA Cookbook on Github

Regardless of the method to download a web document, you will not have access to its DOM from JXA. Alternative approaches, like loading the HTML in a WKWebView object and then calling this object’s executeJavaScript method, will only work if the WKWebView object is visible.

Another possibility to work with the DOM of a web document is to open it in Safari and inject JavaScript into it via Safari’s doJavaScript method. This is illustrated in the chapter on automating applications