0

Possible Duplicate:
Header Location + Content Disposition

I have a page that generates excel report using header content-type and save the generation information on the database (e.g. who generated the report,when etc.) My problem is why I can't redirect the page. below is the sample code/algo

// excel content
/* excel content populates here */

// output to excel file
header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=".$positionFileName);
header("Cache-Control: max-age=0");

// save logs on the database  
/* save logs code executed here */

// redirect page to get the logs on the database that display on the web page
header("location: report.php");  *<--- I can't redirect to report.php*

Here is exactly what I want

the user will do is to select type of report then click button generate to output the excel report (open/save dialog). then after that, the system will going to save the logs of generated report on the database then show it on the page. that's why I want to redirect it again on report.php so that the logs will be get again on the database to display on browser.

Community
  • 1
  • 1
Bryan
  • 1,245
  • 5
  • 22
  • 37
  • 3
    Silly question, perhaps, but have you tried to change `location` to `Location`? Also, if the page is just white, it might be WSOD. – Leonard Oct 30 '12 at 10:29
  • 1
    What do you get ? Any error message ? What do you mean by "I can't" ? – Bgi Oct 30 '12 at 10:29

5 Answers5

2

The headers are colliding. First you say "here comes a document", using Content-Disposition: attachment, and then you say "Oh no, it's not coming, do an additional request to XYZ", using the Location header. You can omit the Content- headers to achieve the same result.

This however works for me:

header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=foo.dat");
header("location: foo.dat");

In that I get redirected to the foo.dat file, which is displayed in the browser (so the Content-headers are ignored, since after the Location-header a new request is issued which does not get the Content-headers in its response. If you want to enforce attachment, either configure your web server to emit those headers for certain extensions or directories, or use fpassthru($filename) without the Location-header to directly emit the file without running into memory errors:

header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=".$positionFileName);
header("Cache-Control: max-age=0");

// save logs on the database  
/* save logs code executed here */

fpasstrhu($positionFileName);

But please note that any output generated during the executing of the code after the first three header()statements will be outputted to the browser, which'll think it is file data.

I guess this is currently also happening, causing the header("location: ...") to fail. Enable error reporting to see why and where there was data printed.

Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
1

It won't work because you're telling the browser that it should expect an Excel file. THEN, after you've told the browser that it should expect an Excel file, you're attempting to redirect to another page. The problem lies in your approach.

Wayne Whitty
  • 19,513
  • 7
  • 44
  • 66
  • Sorry I'm novice on PHP. So what is the best approach for that? – Bryan Oct 30 '12 at 10:45
  • What exactly are you trying to do? i.e. What does the user actually do when they are using this part of your application? – Wayne Whitty Oct 30 '12 at 10:47
  • the user will do is to select type of report then click button generate to output the excel report (open/save dialog). then after that the system will going to save the logs of the generated report on the database then show it on the page after. – Bryan Oct 30 '12 at 10:48
  • what's why I want to redirect to the report.php so that the logs saved on the database will be get again to display it on browser – Bryan Oct 30 '12 at 10:49
  • 1
    Why not read the file, interpret it and then store the results in your DB before redirecting? How are you logging it to DB? Are you logging the entire output to DB? – Wayne Whitty Oct 30 '12 at 10:53
  • e.g i have button generate report on the upper portion of browser then below that is the logs of generated report. after generating the reports, the logs below will be refresh – Bryan Oct 30 '12 at 10:54
  • I'm just logging the report type and the user generates the report on the database. I'm not logging the actual report/file on the database. – Bryan Oct 30 '12 at 11:00
  • Why not log the report type that the user has selected and then redirect? – Wayne Whitty Oct 30 '12 at 11:01
-1

Check that you have not already output anything to the browser.

'location' should be 'Location' usually too.

Brian
  • 8,418
  • 2
  • 25
  • 32
-1

Edit This
header("Location: report.php");

Nirav Ranpara
  • 13,753
  • 3
  • 39
  • 54
-1
header( "Location: http://" . strip_tags( $_SERVER ['HTTP_HOST'] ) . "/report.php" );

Try this.. I always call the HTTP Host checker, to make sure I stay on the same domain.

edit: my bad, i learned it as writting it with a capital letter L ... sorry for the earlier note.

Dorvalla
  • 5,027
  • 4
  • 28
  • 45
  • _"and yes, you have to type it with a capital L"_ - no you don't: [RFC 2616, section 4.2, Message Headers](http://tools.ietf.org/html/rfc2616#section-4.2): _"Each header field consists of a name followed by a colon (":") and the field value. **Field names are case-insensitive**"_. There used to be browsers that assumed/required Capitalized-Header-Fields, but those are silly and should not have to be supported. – CodeCaster Oct 30 '12 at 11:00
  • 1
    Thanks for the headsup. I was taught wrong then, @CodeCaster – Dorvalla Oct 30 '12 at 11:05