how to redirect correctly to the download page

44 views
Skip to first unread message

Niko

unread,
Oct 19, 2012, 4:12:18 PM10/19/12
to nitro...@googlegroups.com
Hi ,
I am trying to create simple scenario:

1.the  user fill the form
2. if everything ok he redirected  to the page there user can read  : "Thank you for downloading !"
3. Download of the file begin.

So I create a form page :

form() ->
    Form = [
 
        #label { text = "Email Address" },
        #textbox { id = emailTextBox, next = downloadButton },

        #p{},
        #button { id = downloadButton,class="save",  text = "Download", postback = fireFile}
    ],

    wf:wire(downloadButton, emailTextBox, #validate { validators = [
        #is_required { text = "Required." },
        #is_email { text = "Enter a valid email address." }
    ]}),

    Form.


event(fireFile) ->
    wf:redirect_from_login("my/page");

event(_) -> ok.


The second page :

body() ->
     wf:info("Start render page"),
    [
        #panel { style="margin: 50px 100px;", body=[
            #h1 { text=" my_page !" },
            #label {text="Thank you for downloading !" },
         
        ]}
    ],
    download().

download() ->
    wf:content_type("application/pdf"),
    %Give a name
    wf:header("Content-Disposition"," attachment; filename=\"myfile.pdf\""),
    wf:header("Content-Transfer-Encoding", "binary"),
    wf:header("Accept-Ranges", "bytes"),
    FileName ="/tmp/file12.pdf",
    {ok,Data} = file:read_file(FileName),
    Data.

The problem is that download starts  without to showing message  "Thank you !".
So how to force nitrogen to show the message ?

Thanks for any advice !




Mark Sharkey

unread,
Oct 19, 2012, 9:27:50 PM10/19/12
to nitro...@googlegroups.com
Hey Niko, 

the reason you are not seeing the "thank you" message is because it's not being returned by the body function - only the last statement gets returned - in this case the download function. 

For some other use cases this is easily fixed by just moving the download function call into the statement block above it. However, without testing, I don't think this will work in your case because of the two different content types (but give it a try and see what happens).

What I think you'll need to do is something like they talk about here


but maybe try a postback instead of a refresh

Cheers,
Mark







--
You received this message because you are subscribed to the Google Groups "Nitrogen Project / The Nitrogen Web Framework for Erlang" group.
To view this discussion on the web visit https://groups.google.com/d/msg/nitrogenweb/-/zPwwDEfrNGEJ.
To post to this group, send email to nitro...@googlegroups.com.
To unsubscribe from this group, send email to nitrogenweb...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/nitrogenweb?hl=en.

Jesse Gumm

unread,
Oct 20, 2012, 2:50:05 AM10/20/12
to nitro...@googlegroups.com
Hey Niko,

The nice thing about most (all?) browsers is that if you do a redirect
to a static file, the browser will just download the file but keep you
on the site.

So that means that you could make the body of the "download page" be
whatever you want, and somewhere in there, do a
wf:redirect("http://url/to/your/file").

That should ensure that the page gets rendered as you want and the
download happens.

That said, if you really want to have Nitrogen stream the file rather
than either letting the webserver handle it or having a reverse proxy
like nginx deal with your static files, you can make a separate module
(called something like downloads) and have the main() function do all
the things you previously had your download() function do.

You can do some URL trickery with wf:path_info() to determine which
file you're retrieving if you have a database or something mapping
some kind of file ID to an actual file on the filesystem.

Say you wanted to do some kind of download like
http://whatever/download/34543756743/my-file.bin

For example, you could do something like this for your download module.

-module(download).
-include_lib("nitrogen_core/include/wf.hrl").

main() ->
Path = wf:path_info(),
case re:match("^(\\d+)/.*",Path,[{capture,all_but_first,binary}]) of
{match, [ID]} -> serve_file(ID);
nomatch -> "Not Found"
end.

serve_file(ID) ->
File = my_file_mapper:get_file_from_id(ID);
download(File).

%% Using most of your download() function
download(FileName) ->
wf:content_type("application/octet-stream"),
wf:header("Content-Disposition"," attachment; filename=\"myfile.pdf\""),
wf:header("Content-Transfer-Encoding", "binary"),
wf:header("Accept-Ranges", "bytes"),
{ok,Data} = file:read_file(FileName),
Data.

That's typically how I deal with a download module that must be served
from Nitrogen, though it's more common for me to redirect to something
like Amazon S3 storage.

It should go without saying that you want to be careful with this
since you're reading the entire file into memory this way with
file:read_file/1, while the webservers like cowboy and yaws will
actually stream the file from disk if it's being served from one of
the config-defined static directories.

-Jesse
--
Jesse Gumm
Owner, Sigma Star Systems
414.940.4866 || sigma-star.com || @jessegumm

Niko

unread,
Oct 21, 2012, 5:55:46 PM10/21/12
to nitro...@googlegroups.com, gu...@sigma-star.com
Thank you very much for the answers  !

Jesse Gumm

unread,
Oct 21, 2012, 11:19:48 PM10/21/12
to nitro...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages