Triggering a file download without any server request

前端 未结 4 1311
粉色の甜心
粉色の甜心 2020-12-06 05:43

Greetings,

I\'m working on a JS-based application that does some complex work and logs some information (actually, up to hundreds of lines) on a

相关标签:
4条回答
  • 2020-12-06 06:27

    I have been down this road, and I also wanted to do it purely on the client-side. But, it is impossible. The only way you can trigger the save dialog without any fuss is by making a HTTP POST request, and having the server respond with a content-disposition header.

    I have your desired functionality in the code snippets on my dusty old blog. I have a form with one hidden field pointed to a custom HTTP handler. Javascript grabs the inner text of the code block, puts it in the hidden field, and submits the form. Server responds with the entire body of the request, along with the required headers. No refresh, you click it and you get a save dialog. Works great!

    0 讨论(0)
  • 2020-12-06 06:30

    This solution is slightly convoluted but would work for your needs, perhaps it's an option.

    Create a custom web server that simply returns the contents of any GET or POST as text/plain.

    Host that web server on the same box as the web application but running on a different port. When you click the Save log button, the request is sent to the custom server and the text file is returned.

    Here's a proof of concept server in Java that will do just that:

    // After running this program, access with your browser at 127.0.0.1:8080
    
    import java.net.*;
    import java.io.*;
    
    public class ReturnTextFile
    {
    
        public static void main(String[] args)
        {
    
        try
        {
            ServerSocket server = new ServerSocket(8080);
            Socket connection = null;
    
            while (true)
            {
    
            try
            {
                connection = server.accept();
    
                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    
                String input = in.readLine();
    
                // TODO: Clean up input
    
                Writer out = new OutputStreamWriter(connection.getOutputStream());
    
                String output = "HTTP/1.1 200 OK\n" +
                        "Connection: close\n" +
                        "Content-Disposition: attachment; filename=log.txt\n" +
                        "Content-Type: text/plain; charset=utf-8\n" +
                        "\n";
    
                output += input;
    
                out.write(output);
    
                out.flush();
    
                connection.close();
            }
            catch (IOException ex)
            {
                ex.printStackTrace();
            }
            finally
            {
                if (connection != null)
                {
                connection.close();
                }
            }
    
            }
    
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
    
        }
    }
    
    0 讨论(0)
  • 2020-12-06 06:37

    Unfortunately this is not something you can do with normal browser capabilities. Something like flash or a browser-specific plugin will get you what you need, but security limitations within javascript will not let you download arbitrary data created within the browser.

    Also the 'data' url is not supported across all browser/version combinations. I am not sure if your users are constrained on what browser they are using or not but that may limit what you can do with that solution.

    0 讨论(0)
  • 2020-12-06 06:47

    You can set the content-type in the data: URL, Something like this:

    data:text/plain,this is some text
    

    However, that still has the problem of the browser automatically rendering it as text. You really have two options that i can see. One is that you set the type to some kind of binary type so that the browser doesn't try and render it, or that you have the type as text/plain and get the user to right-click and save as. Maybe something here can help?

    0 讨论(0)
提交回复
热议问题