For Chrome and Firefox, I have been using a purely JavaScript method.
(My application cannot make use of a package such as Blob.js because it is served from a special engine: a DSP with a WWWeb server crammed in and little room for anything at all.)
function FileSave(sourceText, fileIdentity) {
    var workElement = document.createElement("a");
    if ('download' in workElement) {
        workElement.href = "data:" + 'text/plain' + "charset=utf-8," + escape(sourceText);
        workElement.setAttribute("download", fileIdentity);
        document.body.appendChild(workElement);
        var eventMouse = document.createEvent("MouseEvents");
        eventMouse.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        workElement.dispatchEvent(eventMouse);
        document.body.removeChild(workElement);
    } else throw 'File saving not supported for this browser';
}
Notes, caveats, and weasel-words:
- I have had success with this code in both Chrome and Firefox clients running in Linux (Maipo) and Windows (7 and 10) environments.
- However, if sourceTextis larger than a MB, Chrome sometimes (only sometimes) gets stuck in its own download without any failure indication; Firefox, so far, has not exhibited this behavior. The cause might be some blob limitation in Chrome. Frankly, I just don't know; if anybody has any ideas how to correct (or at least detect), please post. If the download anomaly occurs, when the Chrome browser is closed, it generates a diagnostic such as 
- This code is not compatible with Edge or Internet Explorer; I have not tried Opera or Safari.