1

I am trying to download a file from an ESP32 which is running the PsychicHTTP webserver. For testing, this is just a fixed .CSV file. In HTML:

<div>
<button type="button" onclick="saveFile()">Save file</button>
</div>

In the associated Javascript:

function saveFile() {
  var xhr = new XMLHttpRequest();
  console.log("SAVING FILE");
  xhr.open("GET", "/saveFile", true);
  xhr.send();
}

In the ESP32 code, in the setup for the webserver:

server.on("/saveFile", [](PsychicRequest *request) {
  Serial.println("SAVE FILE REQUEST");
  String filename = "/results/sample.csv";
  PsychicFileResponse response(request, LittleFS, filename, (String&)("text/csv"), true);

  return response.send();
});

I have also made a small mod to the PsychicHTTP webserver code to include "text/csv" as a MIME type.

When this is all running, the webserver receives the GET request for the download, I can see this in the Firefox console and in the ESP32 serial message. However the file doesn't download. ESP32 is at 192.168.0.136 so if I type in 192.168.0.136/saveFile directly in the browser address bar then the file is downloaded and saved. I have seen a few different examples of file downloads in Javascript and they all seem to use either "FETCH" or some form of HTML. Something like this:

function downloadFile(url, fileName) {
  fetch(url, { method: 'get', mode: 'no-cors', referrerPolicy: 'no-referrer' })
    .then(res => res.blob())
    .then(res => {
      const aElement = document.createElement('a');
      aElement.setAttribute('download', fileName);
      const href = URL.createObjectURL(res);
      aElement.href = href;
      aElement.setAttribute('target', '_blank');
      aElement.click();
      URL.revokeObjectURL(href);
    });
};

I can also try the simple HTML version of this when I get time - just using tag with download attribute - as my requirement is pretty simple.

So my two questions:

  • Why does a direct addressing to the download link work from the address bar but the Javascript above does not work?
  • If I use the FETCH example below, do I retain the same code in the ESP32 to respond or is something different required?
8
  • 1
    mode: 'no-cors' you can’t do this if you want to use the response, docs Commented Oct 2, 2024 at 0:09
  • That was just an example I found of the FETCH API. My file is on the same ESP32 so there should be no CORS issues. In my case, looking at the Firefox console, I am getting Referrer-Policy of "strict-origin-when-cross-origin" if that is important. Commented Oct 2, 2024 at 0:39
  • I would expect your download file function to work correctly if you get rid of mode no cors, otherwise it will not work. Commented Oct 2, 2024 at 1:11
  • My current function is the one above - saveFile(). That's the one that doesn't seem to work. downloadFile is an example I found where somebody uses the FETCH API. I haven't tried it yet. Commented Oct 2, 2024 at 1:46
  • 1
    This question is similar to: Prompt file download with XMLHttpRequest. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. Commented Oct 2, 2024 at 14:24

1 Answer 1

1

Maybe not the full answer but I ended up just using the download attribute of the anchor tag. I can use a JS function to set the filename to whatever I need. There are no CORS issues to maange.

Sign up to request clarification or add additional context in comments.

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.