ESP32 PsychicHTTP服务器:JS下载CSV失败但直接链接正常的问题咨询
1. Why direct URL access works but XMLHttpRequest doesn't
When you enter the URL in the browser address bar, the browser initiates a full navigation request. It inspects the response's MIME type (text/csv) and headers, and since CSV is recognized as a downloadable format, it automatically launches the file save dialog.
In contrast, XMLHttpRequest (XHR) only retrieves the raw CSV data in the background as a JavaScript object. The browser doesn't interpret this as a request to download a file unless you explicitly add code to trigger the download dialog. The XHR itself just fetches the content—it doesn't tell the browser to save it to disk.
2. Do you need to modify ESP32 code when using Fetch?
No, your existing PsychicHTTP setup doesn't require modification (as long as it's correctly serving the sample.csv file with the text/csv MIME type). However, you need to adjust your JavaScript to handle the Fetch response and trigger the download manually.
Here's a working Fetch implementation:
async function saveFile() { try { const response = await fetch('/saveFile'); if (!response.ok) throw new Error('Request failed'); const blob = await response.blob(); const downloadUrl = window.URL.createObjectURL(blob); // Create a temporary anchor element to trigger download const link = document.createElement('a'); link.href = downloadUrl; link.download = 'sample.csv'; // Set the desired filename document.body.appendChild(link); link.click(); // Clean up window.URL.revokeObjectURL(downloadUrl); document.body.removeChild(link); } catch (err) { console.error('Download error:', err); } }
Optional ESP32 Improvement
For better compatibility, you can add a Content-Disposition header to the ESP32 response. This explicitly tells the browser to treat the file as an attachment. In PsychicHTTP, you can do this by passing true as the fourth parameter to send():
server.on("/saveFile", HTTP_GET, [](PsychicRequest *request) { // The final "true" enables Content-Disposition: attachment request->send(LittleFS, "/sample.csv", "text/csv", true); });
This change isn't mandatory for the Fetch code to work, but it makes the server response more explicit and consistent across browsers.
内容的提问来源于stack exchange,提问作者Dean Jones

