讓瀏覽器下載檔案後自動重新整理

遇到一個特殊的情況
因為頁面有做 CSRF 的防護,所以當有一些背景動作之後,當前的頁面會因為 CSRF 的問題導致無法運作。
但是頁面中有一個功能是 匯出,所以需要在使用者完成下載檔案的動作之時,必須將頁面重新整理才可以確保不會被 CSRF 陷害。

但是,正常來說在開始送出檔案之後,所有的內容都是檔案內容。
因此無法順利地在使用者完成檔案下載之後才寫重新整理的語法。而如果想要先寫相關設定之後再送出檔案,卻會因為不確定使用者要花費多少的時間才可以完成下載檔案的動作,因此也不是十分容易達成。

後來,在萬能的 stackoverflow 找到了一個神奇的解決方案。

這解決方案,基本上是利用一個特殊的 Content-Type,讓伺服器可以在一次的資料傳輸當中送出兩筆不同類型的資料給瀏覽器。
大致上的程式碼如下:

define('MP_BOUNDARY', '--' . sha1(microtime(true)));

header('Content-Type: multipart/x-mixed-replace; boundary="' . MP_BOUNDARY . '"');
flush();
echo('Content-Type: application/zip' . "\r\n");
echo('Content-Disposition: attachment;filename=foo.zip' . "\r\n");
echo("\r\n");
readfile('foo.zip');
echo(MP_BOUNDARY);
flush();

echo('Content-Type: text/html' . "\r\n");
echo("\r\n");
echo('<html><script type="text/javascript">location.reload();</script></html>');
echo(MP_BOUNDARY . '--');
flush();