Может ли PHP-скрипт обмануть браузер, заставив его думать, что HTTP-запрос завершен?
-
07-07-2019 - |
Вопрос
Сначала я настраиваю свой скрипт на запуск даже после завершения HTTP-запроса
ignore_user_abort(true);
затем удалите какой-нибудь текст.
echo "Thats all folks!";
flush();
Теперь, как я могу обмануть браузер, заставив его думать, что HTTP-запрос завершен?таким образом, я могу продолжать выполнять свою собственную работу без того, чтобы браузер показывал "загрузка страницы".
header(??) // something like this?
Решение
Вот как это сделать. Вы просите браузер прочитать первые N символов вывода, а затем закрыть соединение, пока ваш скрипт продолжает работать, пока он не будет завершен.
<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort(true); // optional
ob_start();
echo ('Text the user will see');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Will not work
flush(); // Unless both are called !
// At this point, the browser has closed connection to the web server
// Do processing here
echo('Text user will never see');
?>
Другие советы
Заголовки не будут работать (это заголовки, поэтому они приходят Первый)
Я не знаю ни одного способа закрыть http-соединение без завершения работы скрипта, хотя я полагаю, что есть какой-то непонятный способ сделать это.
Если вы сообщите нам, что вы хотите сделать после выполнения запроса, это поможет нам дать лучшие предложения.
Но в целом, я бы подумал об одном из следующих:
1) Выполните какой-нибудь простой скрипт командной строки (используя exec ()), который выглядит следующим образом:
#!/bin/sh
php myscript.php <arg1> <arg2> .. <argN> &
Затем запустите это из вашего http-скрипта, связанного следующим образом:
<?PHP
exec('/path/to/my/script.sh');
?>
Или:
2) Напишите другую программу (возможно, постоянно работающий демон или просто какой-нибудь скрипт, который запускается очень часто) и выясните, как ваш код в запросе может передавать ей инструкции.У вас могла бы быть таблица базы данных, которая стоит в очереди на работу, или попытаться заставить ее работать с каким-нибудь плоским файлом.Вы также могли бы заставить свой веб-скрипт вызывать какую-либо команду командной строки, которая заставляет ваш сценарий, не выполненный по запросу, ставить в очередь некоторую работу.
В конце концов, вы этого не делаете хотеть ваш скрипт должен продолжать выполняться после http-запроса.Предполагая, что вы используете mod_php, это означает, что вы будете связывать процесс apache до завершения работы скрипта.
Может быть, этот конкретный комментарий на странице справки php.net поможет:
Теоретически, если HTTP 1.1 keep-alive включен и клиент получает количество символов, которое он ожидает от сервера, он должен обработать его как конец ответа и продолжить и отобразить страницу (сохраняя соединение по-прежнему открыть.) Попробуйте отправить эти заголовки (если вы не можете включить их другим способом): Где Connection: keep-alive
Content-Length: n
n
- это количество символов, отправленных вами в теле ответа (буферизация вывода может помочь вам это подсчитать). Извините, у меня нет времени, чтобы проверить это самостоятельно. Я просто добавляю предложение на случай, если оно сработает.
Лучший способ сделать это - использовать буферизацию вывода. PHP отправляет заголовки, когда все хорошо и готово, но если вы перенесете свой вывод в браузер с помощью ob_ *, вы сможете контролировать заголовки на каждом этапе пути.
Если хотите, вы можете держать отрендеренную страницу в буфере и отправлять заголовки, пока в Китае не взойдет солнце. Именно из-за этой практики вы можете увидеть множество открывающих тегов <?php
, но в настоящее время их нет. Он не позволяет сценарию отправлять заголовки преждевременно, поскольку некоторые из них могут быть рассмотрены.