Communicating with headers is OK but it can be more versatile if you implement your own communication protocol. Simply because you can as you are in total control of both server and client code. So, why not make your communication a bit more verbose and standard by always including 1) operation-status, 2) text message, 3) optional html message, 4) optional JavaScript code to execute (just joking), 5) optional data. All wrapped as JSON hash for example.

Client-to-server communication via sending an XHR (XMLHttpRequest) (generally: AJAX) works on the "same page". No need to reload or move to a new page. The client sends a request to the server which responds with running a script (in your case "download.pl") or routing to a controller, etc. The results are passed back to the caller, i.e. the client's browser and notify your XMLHttpRequest object (your xhhttp) by means of activating callbacks you implemented when you created the object. That's provided the client did not move to a new page or reloaded!

You can implement a number of different callbacks or you can implement just one, onreadystatechange just as you did in your code. This function will be called each time the communication changes a state, and accompanied with appropriate data. And so it can, for example, report on progress, bytes transfered etc, report a server error (500,404) or process the received data if server did send something without complaining. See https://javascript.info/xmlhttprequest for more details.

The callback can then notify the user by *dynamically* creating or changing an HTML element, e.g. a text box's content or popping up a message. This is well documented on the internet.

So, what I suggest is you keep your callback handler mostly unchanged. On state=4 (XHR completed), as you now do, check the server response and alert the user if it was not 200/OK. If it was, then unwrap the "complex" data you received from server in order to check its status, e.g. file-too-big, permission-denied, no-such-file-do-you-want-to-create, (an arbitrarily long list!) etc. And also present the user with the error message/instructions the server sent you. And/or process the data part and decode your image. Which, btw, must be text-encoded (e.g. via base64).

On the server side it looks like this:

... use JSON; use MIME::Base64; my $ret_data = { 'status' => 5, # success 'message' => "here is the file $filename you asked" 'message-html' => "<b>success blah blah for $fileame</b>", 'data' => MIME::Base64::encode_base64($image_binary_data) }; # if using CGI.pm use CGI; my $cgi = CGI->new; print $cgi->header(-type => "application/json", -charset => "utf-8"); print JSON::encode_json($ret_data); # or if using Mojolicious $c->render(json => $ret_data);

1 minute Edit: here is the data I would send on a failure, e.g. file permissions or file-too-big-to-send, or ... One advantage of this method is that you can still send data even on errors.

my $ret_data = { 'status' => -1, # file was too big and I truncated it 'message' => "here is the file $filename you asked but it is truncat +ed" 'message-html' => "<b>success blah blah for $fileame but truncated</ +b>", 'data' => truncate($data) };

bw, bliako


In reply to Re: Sending file as "TEXT" or "BLOB" by bliako
in thread Sending file as "TEXT" or "BLOB" by cristofayre

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.