Execute Javascript to download a file via XMLHttpRequest()

We have a system where we generate .xlsx files and provide download links for them. Obviously, clicking on those links to download a file is not feasible as it would either pop up a native dialogue box that I can’t control, or download directly to a location that is dependent on platform (win, linux, mac) and browser (we might test on different browsers).

My solution is to use ‘Execute Javascript’ to do an XMLHttpRequest call to GET the file using the href of the tag and then return the data to RF… The JS I have so far to do this is

${raw_content}= Execute Javascript let r=new XMLHttpRequest();r.open(“GET”,“${file_url}”,false);r.overrideMimeType(“text/plain; charset=x-user-defined”);r.send(null);return r.responseText;

In theory this should return the binary data for the .xlsx file and it seems to do that. The difficulty is that the resultant string ${raw_content} is a standard Python string (Unicode) and cannot figure out how to decode this back into the correct binary representation to write it to disk so I can open it as an Excel spreadsheet and analyse it.

I’ve tried everything I know… convert to bytes/bytearray… Base64 encode in the browser using JS btoa(…) then decode in python at the other end etc etc etc but I can’t seem to recreate the original binary representation.

Thanks in advance for any help…

Hi Mark,

possibly ${raw_content} is base64 encoded (this is common for transferring files to/from web servers, and all you need to do is decode it.

To confirm if this is the case grab the full string you got in ${raw_content} and past it into an online base64 decoder and see if the resultant string looks like binary data (e.g. https://www.base64decode.org/), if it does paste the decoded string into a text editor and save the file as something.xlsx and see if excel will open it

If that worked then there is a python library for that, so something like this might be all you need to do before using Create Binary File:

${raw_data}=    Evaluate    base64.b64decode(${raw_content}).decode('utf-8')  modules=base64

I thought there was a library with base64 keywords but I can’t remember what it is.

hopefully this helps,

Dave.

Thanks Dave… I wish that was the case but it’s not… ${raw_content} comes through like this…

[info (+0.76s)] ${raw_content} = PK RV  [Content_Types].xmln0E%J ]TUE`E $~c^qJPZQV~;snFVF5"jj6 'g&0A6l26Z5R

| GJAhw\z2l<zF,L
u…

My first attempt was to use Create Binary File with ${raw_content} and it did this…

[info (+0.65s)] ${raw_content} = PK SV  [Content_Types].xmln0E%J ]TUE`E $~c^qJPZQV~;snFVF5"jj6 'g&0A6l26Z5R

| GJAhw\z2l<zF,L
u…
[FAIL] ValueError: bytes must be in range(0, 256)
ValueError: bytes must be in range(0, 256)

From that I figured out that ${raw_content} has some weird unicode chars in it that Create Binary File doesn’t like…

Hi Mark,

Perhaps another approach then;

I found this example where the chrome options are used to set the directory where files should be downloaded to, perhaps this will prevent the prompts?

Actually from what I remember the only browser that pops an OD dialogue by default when downloading is IE, which is windows only and no longer supported anyway.
Chrome, Edge (which is based on Chrome), Firefox, Safari, etc download to a predefined directory unless you right click and choose save as or similar option, so if there is a similar option for the other browsers to set the download location when launching the browser this might be the better way to deal with it.

Dave.

If direct links are available than why not to copy browser cookies and download using python directly?

1 Like