Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.php > #14108 > unrolled thread

Generating "download" pages

Started byLew Pitcher <lew.pitcher@digitalfreehold.ca>
First post2014-07-18 09:55 -0400
Last post2014-07-23 00:38 +0000
Articles 20 on this page of 26 — 7 participants

Back to article view | Back to comp.lang.php


Contents

  Generating "download" pages Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2014-07-18 09:55 -0400
    Re: Generating "download" pages Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-07-18 17:39 +0200
      Re: Generating "download" pages Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2014-07-19 11:38 -0400
        Re: Generating "download" pages Jerry Stuckle <jstucklex@attglobal.net> - 2014-07-19 16:57 -0400
          Re: Generating "download" pages Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2014-07-19 17:06 -0400
      Re: Generating "download" pages Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2014-07-19 11:58 -0400
        Re: Generating "download" pages Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-07-19 19:06 +0200
      Re: Generating "download" pages "Christoph M. Becker" <cmbecker69@arcor.de> - 2014-07-19 19:43 +0200
        Re: Generating "download" pages Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2014-07-19 14:23 -0400
          Re: Generating "download" pages "Christoph M. Becker" <cmbecker69@arcor.de> - 2014-07-19 22:18 +0200
            Re: Generating "download" pages "Christoph M. Becker" <cmbecker69@arcor.de> - 2014-07-19 22:38 +0200
              Re: Generating "download" pages Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2014-07-19 16:54 -0400
                Re: Generating "download" pages Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2014-07-19 17:00 -0400
                  Resolved: Generating "download" pages Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2014-07-20 14:34 -0400
        Re: Generating "download" pages Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-07-19 20:50 +0200
          Re: Generating "download" pages "Christoph M. Becker" <cmbecker69@arcor.de> - 2014-07-19 22:06 +0200
            Re: Generating "download" pages Jerry Stuckle <jstucklex@attglobal.net> - 2014-07-19 16:54 -0400
            Re: Generating "download" pages Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-07-20 00:48 +0200
        Re: Generating "download" pages Arno Welzel <usenet@arnowelzel.de> - 2014-07-20 01:04 +0200
    Re: Generating "download" pages Arno Welzel <usenet@arnowelzel.de> - 2014-07-19 18:17 +0200
      Re: Generating "download" pages Jerry Stuckle <jstucklex@attglobal.net> - 2014-07-19 16:55 -0400
    Re: Generating "download" pages Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2014-07-19 12:25 -0400
      Re: Generating "download" pages Tim Streater <timstreater@greenbee.net> - 2014-07-19 17:36 +0100
        Re: Generating "download" pages Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2014-07-19 13:53 -0400
          Re: Generating "download" pages Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2014-07-19 14:14 -0400
          Re: Generating "download" pages Curtis Dyer <dyer85@gmail.com> - 2014-07-23 00:38 +0000

Page 1 of 2  [1] 2  Next page →


#14108 — Generating "download" pages

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2014-07-18 09:55 -0400
SubjectGenerating "download" pages
Message-ID<6H9yv.30802$el1.16727@fx26.iad>
I'm not certain that what I want can be done, let alone done with PHP, but
please let me describe the function I'm looking for:


On response to a trigger on one web page, I want to be able to generate and
display a new web page, /and/ at the same time, send an associated file as
a download.

The user selects (in this case) "Export recipes" (I'm developing a PHP/MySQL
recipe management application), which causes
1) the page to change to a "Download in progress" page, and
2) a file (in this case, an XML file containing the recipes) to be sent to
the client.

Is this doable? How do I do this with PHP?

-- 
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request

[toc] | [next] | [standalone]


#14109

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2014-07-18 17:39 +0200
Message-ID<6732922.VsfUzaneRC@PointedEars.de>
In reply to#14108
Lew Pitcher wrote:

> On response to a trigger on one web page, I want to be able to generate
> and display a new web page, /and/ at the same time, send an associated
> file as a download.
>  
> The user selects (in this case) "Export recipes" (I'm developing a
> PHP/MySQL recipe management application), which causes
> 1) the page to change to a "Download in progress" page, and
> 2) a file (in this case, an XML file containing the recipes) to be sent to
> the client.
> 
> Is this doable?

Yes.  There are plenty of productive examples on the Web, for example when 
you download from sourceforge.net and use the additional download link 
(client-side scripting will trigger the download dialog automatically, but 
you can cancel that).

> How do I do this with PHP?

There are several ways.  Another is:

  <?php
    header('Content-Disposition: attachment; filename="foo.bar"'); …
    header('Location: http://download.example/foo.bar');
  ?>

  displayed content

This not just a (PHP) language feature, it is using a language-independent 
HTTP feature.  You can use browser developer tools to inspect the HTTP 
response headers, then use the corresponding PHP functions to achieve the 
same.

<http://devtoolsecrets.com/>
<http://php.net/header>
<http://tools.ietf.org/html/rfc2616>

Next time, do your homework, please.


PointedEars 
-- 
> If you get a bunch of authors […] that state the same "best practices"
> in any programming language, then you can bet who is wrong or right...
Not with javascript. Nonsense propagates like wildfire in this field.
  -- Richard Cornford, comp.lang.javascript, 2011-11-14	

[toc] | [prev] | [next] | [standalone]


#14111

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2014-07-19 11:38 -0400
Message-ID<%hwyv.9308$3Y7.9259@fx12.iad>
In reply to#14109
Thanks for the response, Thomas.

Next time, please contain your snark. It ill suits you.

On Friday 18 July 2014 11:39, in comp.lang.php, "Thomas 'PointedEars' Lahn"
<PointedEars@web.de> wrote:

> Lew Pitcher wrote:
> 
>> On response to a trigger on one web page, I want to be able to generate
>> and display a new web page, /and/ at the same time, send an associated
>> file as a download.
>>  
>> The user selects (in this case) "Export recipes" (I'm developing a
>> PHP/MySQL recipe management application), which causes
>> 1) the page to change to a "Download in progress" page, and
>> 2) a file (in this case, an XML file containing the recipes) to be sent
>> to the client.
>> 
>> Is this doable?
> 
> Yes.  There are plenty of productive examples on the Web, for example when
> you download from sourceforge.net and use the additional download link
> (client-side scripting will trigger the download dialog automatically, but
> you can cancel that)

I can, by viewing the source of web pages that use multiple javascript files
with intentionally convoluted logic, and filtering out (in a masterly way)
all that extraneous stuff, find that the web page in question (such as the
download page for a sourceforge project) does *not* include the "server
side" logic that does this. I can /then/ examine the headers from such a
working page, *deduce* that the page sent both html
and "Content-Disposition" (etc.) headers, and *assume* the method of
generating such.

Indeed, this is how I've done it in the past, with poor results. 


>> How do I do this with PHP?
> 
> There are several ways.  Another is:

And, the first was?

> 
>   <?php
>     header('Content-Disposition: attachment; filename="foo.bar"'); …
>     header('Location: http://download.example/foo.bar');
>   ?>
> 
>   displayed content
> 
> This not just a (PHP) language feature, it is using a language-independent
> HTTP feature.

But, to set headers, you need some sort of active language. Mine is PHP.

> You can use browser developer tools to inspect the HTTP 
> response headers, then use the corresponding PHP functions to achieve the
> same.

Or, I can ask in a forum that specializes in such programming, and save
myself the blind alleys, false starts, and mis-assumptions that such an
inspection of the outside effects would bring

[snip suggested tools]


> 
> Next time, do your homework, please.

Condescending, no?

In fact, I've done my homework. And *this* is part of that homework.

Thomas, either be helpful or don't reply. Such snark is not helpful.
-- 
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request

[toc] | [prev] | [next] | [standalone]


#14130

FromJerry Stuckle <jstucklex@attglobal.net>
Date2014-07-19 16:57 -0400
Message-ID<lqem3p$8m0$3@dont-email.me>
In reply to#14111
On 7/19/2014 11:38 AM, Lew Pitcher wrote:
> Thanks for the response, Thomas.
> 
> Next time, please contain your snark. It ill suits you.
> 
> On Friday 18 July 2014 11:39, in comp.lang.php, "Thomas 'PointedEars' Lahn"
> <PointedEars@web.de> wrote:
> 
>> Lew Pitcher wrote:
>>
>>> On response to a trigger on one web page, I want to be able to generate
>>> and display a new web page, /and/ at the same time, send an associated
>>> file as a download.
>>>  
>>> The user selects (in this case) "Export recipes" (I'm developing a
>>> PHP/MySQL recipe management application), which causes
>>> 1) the page to change to a "Download in progress" page, and
>>> 2) a file (in this case, an XML file containing the recipes) to be sent
>>> to the client.
>>>
>>> Is this doable?
>>
>> Yes.  There are plenty of productive examples on the Web, for example when
>> you download from sourceforge.net and use the additional download link
>> (client-side scripting will trigger the download dialog automatically, but
>> you can cancel that)
> 
> I can, by viewing the source of web pages that use multiple javascript files
> with intentionally convoluted logic, and filtering out (in a masterly way)
> all that extraneous stuff, find that the web page in question (such as the
> download page for a sourceforge project) does *not* include the "server
> side" logic that does this. I can /then/ examine the headers from such a
> working page, *deduce* that the page sent both html
> and "Content-Disposition" (etc.) headers, and *assume* the method of
> generating such.
> 
> Indeed, this is how I've done it in the past, with poor results. 
> 
> 
>>> How do I do this with PHP?
>>
>> There are several ways.  Another is:
> 
> And, the first was?
> 
>>
>>   <?php
>>     header('Content-Disposition: attachment; filename="foo.bar"'); …
>>     header('Location: http://download.example/foo.bar');
>>   ?>
>>
>>   displayed content
>>
>> This not just a (PHP) language feature, it is using a language-independent
>> HTTP feature.
> 
> But, to set headers, you need some sort of active language. Mine is PHP.
>  
>> You can use browser developer tools to inspect the HTTP 
>> response headers, then use the corresponding PHP functions to achieve the
>> same.
> 
> Or, I can ask in a forum that specializes in such programming, and save
> myself the blind alleys, false starts, and mis-assumptions that such an
> inspection of the outside effects would bring
> 
> [snip suggested tools]
> 
> 
>>
>> Next time, do your homework, please.
> 
> Condescending, no?
> 
> In fact, I've done my homework. And *this* is part of that homework.
> 
> Thomas, either be helpful or don't reply. Such snark is not helpful.
> 

Lew,

Don't worry - Pointed Head is just being his usual pedantic self.  And
he's once again showing his ignorance, since you can't provide two
responses to one HTTP request (and can't send two different content
types for a single request).

For more info, please see my other updates.

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================

[toc] | [prev] | [next] | [standalone]


#14132

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2014-07-19 17:06 -0400
Message-ID<m5Byv.55770$844.52993@fx14.iad>
In reply to#14130
On Saturday 19 July 2014 16:57, in comp.lang.php, "Jerry Stuckle"
<jstucklex@attglobal.net> wrote:

> On 7/19/2014 11:38 AM, Lew Pitcher wrote:
>> Thanks for the response, Thomas.
>> 
>> Next time, please contain your snark. It ill suits you.
>> 
>> On Friday 18 July 2014 11:39, in comp.lang.php, "Thomas 'PointedEars'
>> Lahn" <PointedEars@web.de> wrote:
[snip]
> 
> Lew,
> 
> Don't worry - Pointed Head is just being his usual pedantic self.

I'm not worried about Thomas. He's free to express his advice and opinions -
and now, having heard and evaluated both, I'm free to ignore him.

> And 
> he's once again showing his ignorance, since you can't provide two
> responses to one HTTP request (and can't send two different content
> types for a single request).

This truth has escaped me. Obviously, there are Jedi Master ways to code
pages so that they /appear/ to provide two (or more) responses to one HTTP
request. I just thought that those ways were readily known with PHP
examples.


> For more info, please see my other updates.

Thanks, I have.

And, you might be interested in the workaround that /I/ concocted, once I
realized the truth about HTTP responses. See Message-ID:
<d0Byv.32651$46.29400@fx19.iad> for a working PHP/HTML example that does
what I wanted my page to do. Others might find it helpful, as well

Thanks again
-- 
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request

[toc] | [prev] | [next] | [standalone]


#14112

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2014-07-19 11:58 -0400
Message-ID<FAwyv.54231$4n.6402@fx31.iad>
In reply to#14109
On Friday 18 July 2014 11:39, in comp.lang.php, "Thomas 'PointedEars' Lahn"
<PointedEars@web.de> wrote:

> Lew Pitcher wrote:
> 
>> On response to a trigger on one web page, I want to be able to generate
>> and display a new web page, /and/ at the same time, send an associated
>> file as a download.
>>  
>> The user selects (in this case) "Export recipes" (I'm developing a
>> PHP/MySQL recipe management application), which causes
>> 1) the page to change to a "Download in progress" page, and
>> 2) a file (in this case, an XML file containing the recipes) to be sent
>> to the client.
>> 
[snip]
>> How do I do this with PHP?
> 
> There are several ways.  Another is:
> 
>   <?php
>     header('Content-Disposition: attachment; filename="foo.bar"'); …
>     header('Location: http://download.example/foo.bar');
>   ?>
> 
>   displayed content
[snip]

Now, having tried your suggested solution, I must tell you that *it did not
work*. So much for /your/ advice.

Here's the PHP I wrote:
 <?php
   header('Content-Disposition: attachment; filename="SixSpot_d.png');
   header('Location: http://merlin.puter.lan/~lpitcher/SixSpot_d.png');
 ?>
 <html>
 <head><title>Trial Sendfile</title></head>
 <body>
 <p>Did you get it?</p>
 </body>
 </html>

There exists, in the source directory, a PNG file named "SixSpot_d.png.
That file can be accessed through the (internal) url
http://merlin.puter.lan/~lpitcher/SixSpot_d.png'

The web page, above, fails to initiate a download or show the specified web
page.

Instead, the web browser (Firefox 5.0.1 for Linux) /displays/ the specified
PNG, instead of the specified html, and /does not/ initiate either an
automatic download into the configured download directory or the Download
menu itself.

Advice (from various sources including PHP.NET) conflict as to which headers
are required, and the order of steps to perform.

So, Thomas, got any more "advice" for me?
-- 
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request

[toc] | [prev] | [next] | [standalone]


#14117

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2014-07-19 19:06 +0200
Message-ID<2715750.mdy3pbUkXS@PointedEars.de>
In reply to#14112
Lew Pitcher wrote:

> So, Thomas, got any more "advice" for me?

When you are ready to communicate in a civilized manner.


PointedEars
-- 
    realism:    HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness:    XHTML 1.1 as application/xhtml+xml
                                                    -- Bjoern Hoehrmann

[toc] | [prev] | [next] | [standalone]


#14118

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2014-07-19 19:43 +0200
Message-ID<lqeamt$jjv$1@solani.org>
In reply to#14109
Thomas 'PointedEars' Lahn wrote:

>> On response to a trigger on one web page, I want to be able to generate
>> and display a new web page, /and/ at the same time, send an associated
>> file as a download.
>>  
>> How do I do this with PHP?
> 
> There are several ways.  Another is:
> 
>   <?php
>     header('Content-Disposition: attachment; filename="foo.bar"'); …
>     header('Location: http://download.example/foo.bar');
>   ?>
> 
>   displayed content

How is that supposed to work?  HTTP can only deliver a single response,
and AFAIK there is no such thing as multipart responses for HTTP.

Anyway, I have tried that idea, and that confirmed my presumption that
the browser is redirected to the Location URI, but the "displayed
content" is not shown.

Using a Refresh header instead of Location might work, but on one hand
the Refresh is not part of the HTTP/1.1 specification (CMIIW), and on
the other the effect is not exactly what the OP asked for.  It seems to
me the only way to get this behavior would be in combination with client
side scripting, what would be on-topic for comp.lang.javascript, for
instance.

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#14122

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2014-07-19 14:23 -0400
Message-ID<0Jyyv.32646$46.296@fx19.iad>
In reply to#14118
On Saturday 19 July 2014 13:43, in comp.lang.php, "Christoph M. Becker"
<cmbecker69@arcor.de> wrote:

> Thomas 'PointedEars' Lahn wrote:
> 
>>> On response to a trigger on one web page, I want to be able to generate
>>> and display a new web page, /and/ at the same time, send an associated
>>> file as a download.
>>>  
>>> How do I do this with PHP?
>> 
>> There are several ways.  Another is:
>> 
>>   <?php
>>     header('Content-Disposition: attachment; filename="foo.bar"'); …
>>     header('Location: http://download.example/foo.bar');
>>   ?>
>> 
>>   displayed content
> 
> How is that supposed to work?  HTTP can only deliver a single response,
> and AFAIK there is no such thing as multipart responses for HTTP.

That's what I suspected.

So, given that I'd like two things to happen (the web page to refresh /and/
a file to download) on one HTTP request (ideally, a POST), what sort of
processing do I need to do in PHP? Or, /can/ I do this at all? Obviously,
some web pages /do/ this sort of thing, so it must be possible, but /how/
they do it is the question I can't answer.

-- 
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request

[toc] | [prev] | [next] | [standalone]


#14125

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2014-07-19 22:18 +0200
Message-ID<lqejqg$ksl$1@solani.org>
In reply to#14122
Lew Pitcher wrote:

 So, given that I'd like two things to happen (the web page to refresh /and/
> a file to download) on one HTTP request (ideally, a POST), what sort of
> processing do I need to do in PHP?

As Thomas had already pointed out (no pun intended), this has nothing to
do with PHP in a strict sense, but is an HTTP issue.

> Or, /can/ I do this at all? 

I still don't think that it is possible via HTTP only.

> Obviously,
> some web pages /do/ this sort of thing, so it must be possible, but /how/
> they do it is the question I can't answer.

Please post an URL to such a ressource.  Maybe others can answer how
they are doing it.

One solution relying on client side ECMAScript support would be to add
the following script element to the document (e.g. at the bottom of the
body element):

  <script>window.location = "file-to-download.ext"</script>

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#14126

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2014-07-19 22:38 +0200
Message-ID<lqekv2$p4h$1@solani.org>
In reply to#14125
Christoph M. Becker wrote:

> One solution relying on client side ECMAScript support would be to add
> the following script element to the document (e.g. at the bottom of the
> body element):
> 
>   <script>window.location = "file-to-download.ext"</script>

Of course the download resource has to be served with a Content-Type
header field that forces the client to treat it as download.

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#14127

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2014-07-19 16:54 -0400
Message-ID<7WAyv.22266$wR1.4120@fx20.iad>
In reply to#14126
On Saturday 19 July 2014 16:38, in comp.lang.php, "Christoph M. Becker"
<cmbecker69@arcor.de> wrote:

> Christoph M. Becker wrote:
> 
>> One solution relying on client side ECMAScript support would be to add
>> the following script element to the document (e.g. at the bottom of the
>> body element):
>> 
>>   <script>window.location = "file-to-download.ext"</script>
> 
> Of course the download resource has to be served with a Content-Type
> header field that forces the client to treat it as download.
> 

Well, I'm not yet familiar enough with ECMAScript/JavaScript to write this
sort of facility into my web pages.

However, I have found a workaround that will suffice until I determine the
proper way to get both updated page /and/ download:

The request page (that which I want to update and redisplay) will contain
within it an (almost) invisible <iframe> linking to a /second/ page. That
second page will /only/ generate the file transfer headers and file.

Together, the two pages will do what I had hoped to do in one page.

Thanks to all for all the advice.
-- 
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request

[toc] | [prev] | [next] | [standalone]


#14131

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2014-07-19 17:00 -0400
Message-ID<d0Byv.32651$46.29400@fx19.iad>
In reply to#14127
On Saturday 19 July 2014 16:54, in comp.lang.php, "Lew Pitcher"
<lew.pitcher@digitalfreehold.ca> wrote:

[snip]

> However, I have found a workaround that will suffice until I determine the
> proper way to get both updated page /and/ download:
> 
> The request page (that which I want to update and redisplay) will contain
> within it an (almost) invisible <iframe> linking to a /second/ page. That
> second page will /only/ generate the file transfer headers and file.
> 
> Together, the two pages will do what I had hoped to do in one page.
> 
> Thanks to all for all the advice.

The main page (sendfile_2.php) looks like this....

<?php
  session_start();
  $showfile = false;

  switch ($_SERVER['REQUEST_METHOD'])
  {
    case 'GET':
      $count = 0;
      break;

    case 'POST':
      $count = 1 + $_SESSION['Count'];
      $showfile = (isset($_POST['Action']) && $_POST['Action'] == 'Send');
      break;
  }
?>
<html>
<head><title>Trial Sendfile</title></head>
<body>
<h1><?php print $count ?></h1>
<p>Did you get it?</p>
<form method="post">
<input type="submit"  name="Action" value="Send"/> 
</form>
<?php
  if ($showfile)
  {
    ?><iframe src="sendfile_2a.php" width="0" height="0" border="0"
frameborder="0" /><?php
  }
?>
</body>
</html>
<?php
  $_SESSION['Count'] = $count;
?>


The "download helper" page (referenced in the iframe and
called "sendfile_2a.php here) looks like this...

<?php
 $file="./SixSpot_d.png";

  header('Content-Type: application/octet-stream');
  header('Content-Disposition: attachment; filename=' . basename($file));
  header('Expires: 0');
  header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  header('Pragma: public');
  header('Content-Length: ' . filesize ($file));
  readfile($file);
  exit(0);
?>


-- 
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request

[toc] | [prev] | [next] | [standalone]


#14136 — Resolved: Generating "download" pages

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2014-07-20 14:34 -0400
SubjectResolved: Generating "download" pages
Message-ID<DYTyv.14973$qR1.6965@fx02.iad>
In reply to#14131
For reference (corrected):

> On Saturday 19 July 2014 17:00, in comp.lang.php, "Lew Pitcher"
> <lew.pitcher@digitalfreehold.ca> wrote:
> 
>> On Saturday 19 July 2014 16:54, in comp.lang.php, "Lew Pitcher"
>> <lew.pitcher@digitalfreehold.ca> wrote:
>> 
>> [snip]
>> 
>>> However, I have found a workaround that will suffice until I determine
>>> the proper way to get both updated page /and/ download:
 
I've refined the technique a bit, and created a standalone PHP page.
 
For reference:
=================== Source code below =================================
<?php

  function SendFile($file)
  {
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename=' . basename($file));
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize ($file));
    readfile($file);
  }

  $msg = null;

  switch ($_SERVER['REQUEST_METHOD'])
  {
    case 'GET':
      if (isset($_GET['type']))
      {
        switch ($_GET['type'])
        {
          case 'HTML':
            SendFile($_SERVER['SCRIPT_FILENAME']);
            break;

          default:
            ?>
            <html><body><p>Sorry, I don't know how to send you a
            <?php print $_GET['type']; ?> file</p></body></html>
            <?php
        }
        exit(0);
      }
      break;

    case 'POST':
      switch ($_POST['Format'])
      {
        case 'HTML':
         $msg = "Downloading ".$_SERVER['SCRIPT_FILENAME']." to you";
         break;
      }
      break;
  }
?>
<html>
<head><title>Trial Sendfile</title></head>
<body>
<h1>Download Form</h1>
<form name="Download" method="post">
<dl>
<dt>Download</dt>
<dd><input type="radio" name="Format" value="HTML"/>webpage</dd>
<dd><input type="radio" name="Format" value="XYZ"/>unknown format</dd>
<dd><input type="submit"/></dd>
</dl>
</form>
<?php
  if (isset($msg))
    printf("<p><b>%s</b></p>\n",$msg);

  /****************************************************************
  ** In order for the page to render properly, we need to ensure **
  ** that the <iframe> appears as the last element of the page   **
  ** Otherwise, the render stops at the <iframe>, and does not   **
  ** show any of the page that follows it.                       **
  ****************************************************************/
  if ($_POST['Format'])
    printf("<iframe src=\"%s?type=%s\" border=\"0\" frameborder=\"0\" />\n",
           $_SERVER['SCRIPT_NAME'],
           $_POST['Format']);
?>
</body>
</html>
=================== Source code above =================================
 
This is a self-contained page:
  GET with no (recognized) parameters will display the initial page
  POST with required parameters will initiate download, and display
       a modified page
  GET with valid type= parameter will download the script
  GET with invalid type= parameter will generate error HTML
 
On initial entry (GET with no parameters), a web form is presented to the
user. The user will select one of the two radio buttons, and click the
Submit button to initiate a POST.
 
On POST, the script will update the page html to include an appropriate
message (either "Downloading ..." or nothing) and emit the new page html.
 
The browser, will render the HTML, including the embedded <iframe>. The
<iframe> will initiate a secondary GET (with type= parameter) to the PHP,
which will determine the validity of the parameter. A valid parameter will
cause the PHP (on this secondary GET) to initiate a file download, while
an invalid parameter will cause the PHP to emit an error webpage, which
will display in the original POSTs <iframe>.
 
Thus, the /appearance/ of an updating webpage that simultaneously
downloads a file the the client system.
 


-- 
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request

[toc] | [prev] | [next] | [standalone]


#14123

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2014-07-19 20:50 +0200
Message-ID<1978758.sLNZCN5jEe@PointedEars.de>
In reply to#14118
Christoph M. Becker wrote:

> Thomas 'PointedEars' Lahn wrote:
>>> On response to a trigger on one web page, I want to be able to generate
>>> and display a new web page, /and/ at the same time, send an associated
>>> file as a download.
>>>  
>>> How do I do this with PHP?
>> 
>> There are several ways.  Another is:
>> 
>>   <?php
>>     header('Content-Disposition: attachment; filename="foo.bar"'); …
>>     header('Location: http://download.example/foo.bar');
>>   ?>
>> 
>>   displayed content
> 
> How is that supposed to work?  HTTP can only deliver a single response,

There *is* only a single response delivered at the same time.

> and AFAIK there is no such thing as multipart responses for HTTP.

There is; that is the purpose of the “Content-Disposition” header field.

<http://tools.ietf.org/html/rfc6266>
 
> Anyway, I have tried that idea, and that confirmed my presumption that
> the browser is redirected to the Location URI, but the "displayed
> content" is not shown.

Apparently it depends on how and to where you redirect.  Most certainly 
those two header fields are not sufficient, but then again I never claimed 
they were.  I fact, I had said how I arrived at my suggestion, and referred 
the OP to additional documentation (which apparently nobody bothered to 
read).
 
AISB, I have found this on sourceforge.net.  I went to 

<http://sourceforge.net/projects/viplugin/files/viplugin/0.2.11/viPlugin_0.2.11_E30.zip/download?use_mirror=sunet&r=&use_mirror=sunet> 

and canceled the download dialog that appeared.  Then I clicked on the link 
with caption “direct link”.  According to Chrome Dev Tools, this issues the 
following HTTP request:

,----
| Remote Address:216.34.181.59:80
| Request 
URL:http://downloads.sourceforge.net/project/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fviplugin%2Ffiles%2Flatest%2Fdownload&ts=1405792642&use_mirror=netcologne
| Request Method:GET
| Status Code:302 Found
| 
| Request Headers (source)
| 
| GET 
/project/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fviplugin%2Ffiles%2Flatest%2Fdownload&ts=1405792642&use_mirror=netcologne 
HTTP/1.1
| Host: downloads.sourceforge.net
| Connection: keep-alive
| Cache-Control: no-cache
| Accept: 
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
| Pragma: no-cache
| User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like 
Gecko) Chrome/34.0.1847.137 Safari/537.36
| Referer: 
http://sourceforge.net/projects/viplugin/files/viplugin/0.2.11/viPlugin_0.2.11_E30.zip/download?use_mirror=sunet&r=&use_mirror=sunet
| Accept-Encoding: gzip,deflate,sdch
| Accept-Language: de-CH,de;q=0.8,en-US;q=0.6,en;q=0.4
| Cookie: __utma=191645736.1110356561.1304966085.1405697254.1405792585.104; 
__utmb=191645736.6.9.1405792650797; __utmc=191645736; 
__utmz=191645736.1405344204.102.90.utmcsr=tvbrowser.org|utmccn=(referral)|
utmcmd=referral|utmcct=/index.php; __utmv=191645736.|
5=AB%20Test=4091748957%3A=1; sf_mirror_attempt=viplugin:sunet|
netcologne:/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip
| 
| Response Headers (source)
| 
| HTTP/1.1 302 Found
| Content-Type: text/html
| Content-Length: 0
| Content-Disposition: attachment; filename="viPlugin_0.2.11_E30.zip"
| Date: Sat, 19 Jul 2014 17:58:15 GMT
| Location: 
http://netcologne.dl.sourceforge.net/project/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip
| Server: lighttpd
| Set-Cookie: sf_mirror_attempt=viplugin:sunet|netcologne|
netcologne:/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip; expires=Sat, 
19-Jul-2014 18:00:15 GMT; Path=/
| X-Frame-Options: SAMEORIGIN
`----

Note that the response body is displayed as empty.

But for the next request, triggered by that response:

,----
| Remote Address:78.35.24.46:80
| Request 
URL:http://netcologne.dl.sourceforge.net/project/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip
| Request Method:GET
| Status Code:200 OK
| 
| Request Headers (source)
| 
| GET /project/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip HTTP/1.1
| Host: netcologne.dl.sourceforge.net
| Connection: keep-alive
| Cache-Control: no-cache
| Accept: 
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
| Pragma: no-cache
| User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like 
Gecko) Chrome/34.0.1847.137 Safari/537.36
| Referer: 
http://sourceforge.net/projects/viplugin/files/viplugin/0.2.11/viPlugin_0.2.11_E30.zip/download?use_mirror=sunet&r=&use_mirror=sunet
| Accept-Encoding: gzip,deflate,sdch
| Accept-Language: de-CH,de;q=0.8,en-US;q=0.6,en;q=0.4
| Cookie: __utma=191645736.1110356561.1304966085.1405697254.1405792585.104; 
__utmb=191645736.6.9.1405792650797; __utmc=191645736; 
__utmz=191645736.1405344204.102.90.utmcsr=tvbrowser.org|utmccn=(referral)|
utmcmd=referral|utmcct=/index.php; __utmv=191645736.|
5=AB%20Test=4091748957%3A=1
| 
| Response Headers (source)
| 
| HTTP/1.1 200 OK
| Content-Type: application/octet-stream
| Content-Length: 161071
| Connection: close
| Accept-Ranges: bytes
| Date: Sat, 19 Jul 2014 17:58:15 GMT
| ETag: "181f60-2752f-3d7fa7c386b00"
| Last-Modified: Tue, 13 Apr 2004 22:35:56 GMT
| Server: Apache/2.2.22 (Debian)
`----

I do not understand yet why the “Content-Disposition” header field was used; 
maybe it has to do with the fact that the HTTP "connection" was not closed.

I think the relevant fact here is that the target resource is served with 
“Content-Type: application/octet-stream”, because that is known to trigger a 
download dialog instead of navigation.  (It would not work, for example, 
with PNG resources by default, because those are served with “Content-Type: 
image/png” by default and the browser would be able to display the resource, 
which it does after self-navigation.)

[Note that I must and can strongly recommend the Vrapper plugin, to be found 
on the Eclipse Marketplace and compatible with Eclipse 4.4.0 at least, over 
the viPlugin developed for Eclipse 3.0.  I just had this URI in my history 
from months, if not years, ago.]

> Using a Refresh header instead of Location might work, but on one hand
> the Refresh is not part of the HTTP/1.1 specification (CMIIW),

Yes, it has only been claimed, but not substantiated, to be a quasi-standard 
introduced by Netscape, that is supported by “just about every browser”.

<http://stackoverflow.com/questions/283752/refresh-http-header>

> and on the other the effect is not exactly what the OP asked for.

I think it would, given the appropriate header.


PointedEars
-- 
> If you get a bunch of authors […] that state the same "best practices"
> in any programming language, then you can bet who is wrong or right...
Not with javascript. Nonsense propagates like wildfire in this field.
  -- Richard Cornford, comp.lang.javascript, 2011-11-14

[toc] | [prev] | [next] | [standalone]


#14124

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2014-07-19 22:06 +0200
Message-ID<lqej4g$ho4$2@solani.org>
In reply to#14123
Thomas 'PointedEars' Lahn wrote:

> Christoph M. Becker wrote:
>
>> and AFAIK there is no such thing as multipart responses for HTTP.
> 
> There is; that is the purpose of the “Content-Disposition” header field.
> 
> <http://tools.ietf.org/html/rfc6266>

Um, I am somewhat confused.  RFC 6266 says (emphasis mine):

| The Content-Disposition response header field is used to convey
| additional information about *how to process the response payload*,
| and also can be used to attach additional metadata, such as the
| filename to use when *saving the response payload locally*.

This seems to be completely different then e.g. "Content-Type:
multipart/alternative" for emails.

> | Response Headers (source)
> | 
> | HTTP/1.1 302 Found
> | Location: 
> http://netcologne.dl.sourceforge.net/project/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip
> 
> Note that the response body is displayed as empty.

This is not surprising, as the HTTP response status code is "302 Found",
which redirects to the URI given in the Location header field.

> I think the relevant fact here is that the target resource is served with 
> “Content-Type: application/octet-stream”, because that is known to trigger a 
> download dialog instead of navigation.

ACK.  However, the content that could be saved, is the payload of the
very response that contained the Content-Type header field.

> <http://stackoverflow.com/questions/283752/refresh-http-header>

Thanks for the confirmation.

[Sorry, I had to snip more of the former discussion than I liked,
because my newsserver doesn't allow too much quoted content.]

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#14128

FromJerry Stuckle <jstucklex@attglobal.net>
Date2014-07-19 16:54 -0400
Message-ID<lqelua$8m0$1@dont-email.me>
In reply to#14124
On 7/19/2014 4:06 PM, Christoph M. Becker wrote:
> Thomas 'PointedEars' Lahn wrote:
> 
>> Christoph M. Becker wrote:
>>
>>> and AFAIK there is no such thing as multipart responses for HTTP.
>>
>> There is; that is the purpose of the “Content-Disposition” header field.
>>
>> <http://tools.ietf.org/html/rfc6266>
> 
> Um, I am somewhat confused.  RFC 6266 says (emphasis mine):
> 
> | The Content-Disposition response header field is used to convey
> | additional information about *how to process the response payload*,
> | and also can be used to attach additional metadata, such as the
> | filename to use when *saving the response payload locally*.
> 
> This seems to be completely different then e.g. "Content-Type:
> multipart/alternative" for emails.
> 
>> | Response Headers (source)
>> | 
>> | HTTP/1.1 302 Found
>> | Location: 
>> http://netcologne.dl.sourceforge.net/project/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip
>>
>> Note that the response body is displayed as empty.
> 
> This is not surprising, as the HTTP response status code is "302 Found",
> which redirects to the URI given in the Location header field.
> 
>> I think the relevant fact here is that the target resource is served with 
>> “Content-Type: application/octet-stream”, because that is known to trigger a 
>> download dialog instead of navigation.
> 
> ACK.  However, the content that could be saved, is the payload of the
> very response that contained the Content-Type header field.
> 
>> <http://stackoverflow.com/questions/283752/refresh-http-header>
> 
> Thanks for the confirmation.
> 
> [Sorry, I had to snip more of the former discussion than I liked,
> because my newsserver doesn't all ow too much quoted content.]
> 

Christopher,

Don't worry, Pointed Head is just showing his ignorance again.  You are
correct - you can't send two different URLs as a response to a single
request.

The easiest way to do it, IMHO, is to just put a javascript request in
the onload event (of the <body> tag).  Have that perform the download.

Arno's idea is interesting, also.  I admit I haven't tried it, but it
would be worth looking at when I get a few minutes, probably next week.

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================

[toc] | [prev] | [next] | [standalone]


#14133

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2014-07-20 00:48 +0200
Message-ID<22681408.NiNFdGaATJ@PointedEars.de>
In reply to#14124
Christoph M. Becker wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Christoph M. Becker wrote:
>>> and AFAIK there is no such thing as multipart responses for HTTP.
>> 
>> There is; that is the purpose of the “Content-Disposition” header field.
>> 
>> <http://tools.ietf.org/html/rfc6266>
> 
> Um, I am somewhat confused.  RFC 6266 says (emphasis mine):
> 
> | The Content-Disposition response header field is used to convey
> | additional information about *how to process the response payload*,
> | and also can be used to attach additional metadata, such as the
> | filename to use when *saving the response payload locally*.
> 
> This seems to be completely different then e.g. "Content-Type:
> multipart/alternative" for emails.

It is not all that different.

>> | Response Headers (source)
>> | 
>> | HTTP/1.1 302 Found
>> | Location:
>> 
http://netcologne.dl.sourceforge.net/project/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip
>> 
>> Note that the response body is displayed as empty.
> 
> This is not surprising, as the HTTP response status code is "302 Found",
> which redirects to the URI given in the Location header field.

ACK.  It would appear I was partially mistaken and you were right.  The link 
on sourceforge.net appears to be no different than any other download link, 
except that server-side redirection is used.

>> I think the relevant fact here is that the target resource is served with
>> “Content-Type: application/octet-stream”, because that is known to
>> trigger a download dialog instead of navigation.
> 
> ACK.  However, the content that could be saved, is the payload of the
> very response that contained the Content-Type header field.

Not necessarily.  Such content can be part of a multi-part message.
 
>> <http://stackoverflow.com/questions/283752/refresh-http-header>
> 
> Thanks for the confirmation.

I have created testcases:

<http://pointedears.de/scripts/php/test/download-redirect>
<http://pointedears.de/scripts/php/test/download-multipart>
<http://pointedears.de/scripts/php/test/download-refresh>

The first and third one redirect/refresh to

<http://pointedears.de/scripts/php/test/download-redirect2>

All three trigger the download dialog in Chromium 34.  However, only the 
latter also displays the HTML document at the same time, even though I 
specified a relative URI-reference.  Since the “Refresh” header field is so 
far a non-standard feature, either it should not be used or it should be 
used as an alternative to client-side scripting (as you suggested), with a 
“direct link” in case neither works (as SourceForge does).  One must decide 
for either HTTP or client-side scripting as using both might trigger the 
download two times.

“download-multipart” and “download-refresh” take parameters to use “Content-
Disposition: inline” instead of “attachment”, and to use the “meta” element 
instead of the HTTP header field, respectively.

Append “.phps” to the URIs for the source code.


I still do not understand why SourceForge would use the “Content-
Disposition” header field in their redirect as the message body truly is 
empty:

$ GET -Se 
'http://downloads.sourceforge.net/project/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fviplugin%2F&ts=1405807555&use_mirror=heanet' 
| head -n 30
GET 
http://downloads.sourceforge.net/project/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fviplugin%2F&ts=1405807555&use_mirror=heanet
302 Found
Connection: close
Date: Sat, 19 Jul 2014 22:08:02 GMT
Location: 
http://heanet.dl.sourceforge.net/project/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip
Server: lighttpd
Content-Length: 0
Content-Type: text/html
Client-Date: Sat, 19 Jul 2014 22:08:02 GMT
Client-Peer: 216.34.181.59:80
Client-Response-Num: 1
Content-Disposition: attachment; filename="viPlugin_0.2.11_E30.zip"
Set-Cookie: 
sf_mirror_attempt=viplugin:heanet:/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip; 
expires=Sat, 19-Jul-2014 22:10:02 GMT; Path=/
X-Frame-Options: SAMEORIGIN

GET 
http://heanet.dl.sourceforge.net/project/viplugin/viplugin/0.2.11/viPlugin_0.2.11_E30.zip
200 OK
Connection: close
Date: Sat, 19 Jul 2014 22:08:02 GMT
Accept-Ranges: bytes
ETag: "1011c768e-2752f-3d7fa7c386b00"
Server: Apache/2.2.14
Content-Length: 161071
Content-Type: application/octet-stream
Last-Modified: Tue, 13 Apr 2004 22:35:56 GMT
Client-Date: Sat, 19 Jul 2014 22:08:05 GMT
Client-Peer: 193.1.193.66:80
Client-Response-Num: 1

PK[zipped content]

> [Sorry, I had to snip more of the former discussion than I liked,
> because my newsserver doesn't allow too much quoted content.]

I know what you mean as I am also using this server and recommended it to 
you.  This is its major (but AFAICS only) disadvantage.  TINSTAAFL.


PointedEars
-- 
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
  -- Richard Cornford, cljs, <f806at$ail$1$8300dec7@news.demon.co.uk>

[toc] | [prev] | [next] | [standalone]


#14134

FromArno Welzel <usenet@arnowelzel.de>
Date2014-07-20 01:04 +0200
Message-ID<53CAF981.809@arnowelzel.de>
In reply to#14118
Christoph M. Becker, 2014-07-19 19:43:

> Thomas 'PointedEars' Lahn wrote:
> 
>>> On response to a trigger on one web page, I want to be able to generate
>>> and display a new web page, /and/ at the same time, send an associated
>>> file as a download.
>>>  
>>> How do I do this with PHP?
>>
>> There are several ways.  Another is:
>>
>>   <?php
>>     header('Content-Disposition: attachment; filename="foo.bar"'); …
>>     header('Location: http://download.example/foo.bar');
>>   ?>
>>
>>   displayed content
> 
> How is that supposed to work?  HTTP can only deliver a single response,
> and AFAIK there is no such thing as multipart responses for HTTP.

It will not work - the browser will likely follow the Location header
and just ignore the Content-Disposition.

> Using a Refresh header instead of Location might work, but on one hand
> the Refresh is not part of the HTTP/1.1 specification (CMIIW), and on
> the other the effect is not exactly what the OP asked for.  It seems to
> me the only way to get this behavior would be in combination with client
> side scripting, what would be on-topic for comp.lang.javascript, for
> instance.

Yep - it's right, a Refresh header is not part of HTTP/1.1 - but most
browsers will still accept it (at least when using <meta
http-equiv="refresh" ...>) and behave as expected. As a fall back one
should offer a direct link within the displayed content anyway - since
client side scripting may also not work if the user did not enable it.



-- 
Arno Welzel
http://arnowelzel.de
http://de-rec-fahrrad.de
http://fahrradzukunft.de

[toc] | [prev] | [next] | [standalone]


#14113

FromArno Welzel <usenet@arnowelzel.de>
Date2014-07-19 18:17 +0200
Message-ID<53CA9A30.4090603@arnowelzel.de>
In reply to#14108
Lew Pitcher, 2014-07-18 15:55:

> I'm not certain that what I want can be done, let alone done with PHP, but
> please let me describe the function I'm looking for:
> 
> 
> On response to a trigger on one web page, I want to be able to generate and
> display a new web page, /and/ at the same time, send an associated file as
> a download.
> 
> The user selects (in this case) "Export recipes" (I'm developing a PHP/MySQL
> recipe management application), which causes
> 1) the page to change to a "Download in progress" page, and
> 2) a file (in this case, an XML file containing the recipes) to be sent to
> the client.
> 
> Is this doable? How do I do this with PHP?

I would solve it this way:

A PHP script displays the page *and* also generates a
META-Refresh-Header to redirect the browser to another script (or the
same whith an additional parameter) which will then generate the content
to be downloaded.

As a rough example (untested and not complete - just to get the idea):

<?php
//
// getfile.php
//

if(!isset($_GET['download'))
{
?>
<!DOCTYPE html>
<html>
<head>
<meta
  http-equiv="refresh"
  content="5; url=http://example.com/getfile.php?download=1" />
<title>Download</title>
</head>
<body>
<p>If your download does not start automatically,
<a href="http://example.com/getfile.php?download=1">click here</a>.</p>
</body>
</html>
<?
}
else
{
  header("Content-Disposition: attachment; filename=download.xml");

  // Add XML output to be downloaded here...
}
?>


-- 
Arno Welzel
http://arnowelzel.de
http://de-rec-fahrrad.de
http://fahrradzukunft.de

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.php


csiph-web