2016-10-31 4 views
2

У меня есть кнопка загрузки на моей стороне клиента. После нажатия кнопки некоторые заголовки устанавливаются на сервере с помощью PHP для запуска загрузки.Как вернуть строку клиенту после установки заголовка

//code snippet: 
$filename = basename($datei); 

$size = filesize($datei); 
$this->response->setHeader('Content-Type', "application/force-download", TRUE); 
$this->response->setHeader('Content-Disposition', 'attachment; filename='.$filename , TRUE); 
$this->response->setHeader('Content-Length', $size, TRUE); 

return "TEST"; //<--code will never go this far, it is ignored 

Загрузка работает. Но я никогда не получаю что-то возвращенное как ответ, но заголовок. Как я могу вернуть что-то, например. строка после запуска загрузки?

Кажется, что невозможно вернуть что-то клиенту после установки заголовка.


ФОН

В основном моя цель состояла в том, чтобы показать и скрыть значок загрузки, например, покажете, что пиннер находится внутри кнопки загрузки, пока файл все еще загружается, и спрячьте его снова после завершения загрузки. Чтобы узнать, закончилась ли загрузка, я подумал, что могу просто вернуть что-то с сервера клиенту, чтобы клиент знал об этом, например. «загрузка выполнена успешно».

Но я не уверен, что это будет работать в любом случае, может быть, ответ придет до того, как загрузка еще закончится.

+0

Для тех, кто читает этот вопрос, и так же запутался, как и я, разными редакциями и плохими формулировками: - чтобы вернуть строку после настройки заголовков, вы можете. (используйте «echo», а не «return» в коде, и он работает). - для отправки как загружаемого файла, так и другой строки за один раз и JS-процесс, вы можете. (Пример слишком длинный для комментариев, есть также оговорки). - использовать заголовки загрузки, а также добавить другую строку для отдельной обработки в JS, вы не можете (как сказал выбранный ответ). Но есть находки (открытые в отдельном окне, являющиеся очевидными, как упоминалось в ответе). – Robbie

+0

Я всегда получаю «Этот запрос не имеет доступных данных ответа». Я пробовал «echo» и «return», однако загрузка началась. – Black

+1

Это сработает - эхо добавляется к загрузке, но на самом деле ввернет то, что вы пытаетесь сделать, но оно делает то, что вы просили. Для чего вы _really_ хотите сделать (например, взаимодействие JS при загрузке или прогрессах), посмотрите на API потоковой передачи для Javascript (я думаю, что он поддерживает IE10 +?), Чтобы вытащить файл как поток данных И дополнительную информацию (как вы это ваш звонок, или вы можете просто откупорить, как только начнется загрузка); а затем используйте saveA для сохранения файловой части данных. Вам по-прежнему потребуется резервное копирование для других браузеров и немного поиграть, чтобы заставить его работать. – Robbie

ответ

2

Вы не можете. Не тратьте свое время на поиски взлома, а скорее создайте страницу для загрузки.

Когда вы говорите браузер (используя заголовки), которые вы собираетесь предоставить файл для загрузки, как здесь

$this->response->setHeader('Content-Type', "application/force-download", TRUE); 

Тогда все довольно недавние браузеры будут следовать этому совету и загрузите файл, после чего они надевают Не беспокойтесь, если PHP сумеет что-то повторить в конце или нет, им это не нужно.

Ваш код PHP не игнорируется, он обрабатывается просто отлично. PHP не мешает вам иметь какой-либо код после предоставления некоторых заголовков для браузера. Просто, как только вы сказали клиенту, что вы собираетесь вернуть файл для загрузки, он не беспокоит, какой другой текст вы хотите вывести. На самом деле это будет считаться частью файла загрузки. Вы не видите его в своем файле, потому что его return, который не полезен в этом контенте, попробуйте echo.

Когда вы предоставляете заголовок Content Type, вы должны отправить контент именно этого типа, если хотите, чтобы браузер успешно понял ответ вашего сервера.

Посмотрите на все основные сайты загрузки, почти у всех из них есть их настройки загрузки, так что, когда вы нажимаете ссылку для загрузки, вы перенаправляетесь на другую страницу, которая говорит «Ваша загрузка начнется вскоре ...» и между тем они инициируют другой запрос на свою страницу загрузки, которая делает именно это; предоставляет файл для загрузки.

Так что в одном запросе вы не можете смешивать эти два вместе с любым количеством совместимости браузера.

+0

В основном моя цель состояла в том, чтобы показать и скрыть значок прядильщика, например. покажите пинкер в кнопке во время загрузки файла и скройте его снова после завершения загрузки. – Black

-1

Ну я использую рамку MVC и в моем контроллере у меня есть метод, который делает это, и нет никакой необходимости повторно загрузить исходную страницу, откуда скачать инициировано:

// Define headers 
header("Cache-Control: public"); 
header("Content-Description: File Transfer"); 
header("Content-Disposition: attachment; filename=$file_name"); 
header("Content-Type: application/zip"); 
header("Content-Transfer-Encoding: binary"); 
// Read the file 
readfile($filePath); 
exit; 
+0

Для меня нет, загрузка работает и без перезагрузки. Но мне нужно перезагрузить по другим причинам сразу после загрузки. – Black

0

Чтобы завершить текущий сценарий вы можете использовать return, однако при использовании в скрипте верхнего уровня (как у вас есть) он завершит выполнение, но не будет возвращать какое-либо возвращаемое значение или выводить что-либо как часть ответа HTTP. Для этого вам нужно exit (но см. Ниже).

return может только передать обратно значение для заходящих сценариев:

  • при использовании в включаемый/требуется, это закончится, которые включают/требуют и передать значение обратно вызова сценария
  • при использовании в функция, она закончится этой функцией и передать значение обратно вызов сценария

для завершения текущего сценария и вывод значения в качестве части для ответа HTTP, вы можете использовать exit (http://php.net/manual/en/function.exit.php) или die (то же, что и выход). Но exit может изменить свое поведение, когда вы передаете параметр:

  • если строки, он будет посылать как часть ответа HTTP
  • если целое число, он будет использовать это в качестве кода выхода (для командной строки Применение).

Для вывода ничего, чтобы получить "вернулся" в качестве части ответа HTTP, используйте echo. (http://php.net/manual/en/function.echo.php). Это выведет все, что может быть преобразовано в строку (т.для вывода целого числа или строки) и не изменять поведение, если целое число или строка, как exit.


Самый безопасный вариант, поэтому:

  • всегда использовать echo послать что-то обратно в часть ответа HTTP
  • всегда использовать exit закончить выполнение;
  • использование возврат внутри функций или файлов, которые вы знаете, будет «включено» (и, возможно, передать обратно возвращаемое значение)

В идеале (чтобы избежать возможных ambiguation в коде) для ответа HTTP, не добавляйте возвращайте значения для выхода, если вы не программируете интерфейс командной строки. т.е. для HTTP, используйте

// Outputs something and exists 
echo 'TEST'; 
exit; 

или

// Outputs something and exists 
echo 1; 
exit; 

Если вы выводите файл (а не переменная у вас есть в памяти) посмотреть на readfile() (http://php.net/manual/en/function.readfile.php), который будет выводить поток файла в ответ HTTP. (Сопровождаемый exit;)

// Outputs a file to HTTP response 
readfile('/path/To/My/File/MyFile.txt'); 
exit; 

* Бонус к сведению: exit, echo и return не являются функциями, сами по себе, но языковые конструкции. Возвратные значения для exit и return не должны указываться в скобках. Он будет работать, но руководство по PHP рекомендует против него. echo может использовать параметры, и действительно, если вы передаете более одного значения для вывода.

Неправильно:

  • выход ('Test');
  • return ('TEST');

Правильно:

  • выхода 'ТЕСТ';
  • возвращение 'TEST';
  • echo 'TEST';
  • эхо ('TEST', 'MORE'),
+1

Я действительно не думаю, что OP хочет это знать. OP хочет знать, как предоставить файл загрузки и какой-либо текст в одном единственном ответе на HTTP. –

+0

Я непосредственно обратился к вопросу, как задал вопрос, то есть почему «возвращает» TEST »;' ничего не возвращает. Тем не менее, ФП значительно изменил этот вопрос с первого проекта - вопрос должен быть закрыт, и новый открывается, если это не проблема, которую нужно решить. – Robbie

+0

Я вижу, имеет смысл тогда. Я не видел истории изменений –

Смежные вопросы