Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.php > #14108 > unrolled thread
| Started by | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| First post | 2014-07-18 09:55 -0400 |
| Last post | 2014-07-23 00:38 +0000 |
| Articles | 20 on this page of 26 — 7 participants |
Back to article view | Back to comp.lang.php
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 →
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2014-07-18 09:55 -0400 |
| Subject | Generating "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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2014-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]
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2014-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]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2014-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]
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2014-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]
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2014-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2014-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]
| From | "Christoph M. Becker" <cmbecker69@arcor.de> |
|---|---|
| Date | 2014-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]
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2014-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]
| From | "Christoph M. Becker" <cmbecker69@arcor.de> |
|---|---|
| Date | 2014-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]
| From | "Christoph M. Becker" <cmbecker69@arcor.de> |
|---|---|
| Date | 2014-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]
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2014-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]
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2014-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]
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2014-07-20 14:34 -0400 |
| Subject | Resolved: 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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2014-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]
| From | "Christoph M. Becker" <cmbecker69@arcor.de> |
|---|---|
| Date | 2014-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]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2014-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2014-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]
| From | Arno Welzel <usenet@arnowelzel.de> |
|---|---|
| Date | 2014-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]
| From | Arno Welzel <usenet@arnowelzel.de> |
|---|---|
| Date | 2014-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