• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

Php и Ajax счетчик загрузки файлов: как узнать загрузил ли пользовател

  • Автор темы IRinat
  • Дата начала
I

IRinat

Друзья!
Счетчик написан на PHP и AJAX. При нажатии на кнопку «Download» счетчик инкрементируется на 1 и высылает пользователю файл на сохранение. Статистика скачиваний хранится в текстовом файле "download-stat/01.stat" на сервере. Данные из файла считываются 1 раз при загрузке страницы. При нажатии кнопки «Download» файл download.html инкрементирует счетчик(статистика еще раз считывается из файла и отправляется AJAX обратно на страницу index.html), а файл get.php выдает ссылку на скачивание. Файлы для загрузки – картинки из папки pictures, кот. называются 01.jpg, 02.jpg и т.д.

index.html

PHP:
<script src="prototype.js"></script>
…
<span style="font-weight:bold;" id="result01"><script language="php">
$filename = "download-stat/01.stat"; //статистика по картинке 01.jpg 
if(file_exists($filename))
{
$file = fopen($filename,"rb");
flock($file,LOCK_EX);
$content = fread($file,filesize($filename));
fclose($file);
echo($content);
}</script></span><br />
<form id="myform">
<input type="button" onclick="dosubmit('01')" value="Download">// 01.jpg - картинка, кот. будем загружать
</form>
<script language="javascript">
function dosubmit(num) {
new Ajax.Updater( 'result'+num, 'download.html?filename='+num, { method: 'post',
parameters: $('myform').serialize() } );
form = document.createElement("form");
form.method = "POST";
form.action = '[адрес_сайта]/get.php?filename='+num;
form.target = "_self";
document.body.appendChild(form);
form.submit();
}
</script>
……..

Файл prototype.js реализует функции AJAX, т.е. динамически записывает данные в <span style="font-weight:bold;" id="result01"></span> на странице index.html

download.html
PHP:
<script language="php">
$file = "pictures/".$_GET['filename'].".jpg";
if (file_exists($file)) {
$stat_file_path = "download-stat/".$_GET['filename'].".stat";
$file_stat = fopen($stat_file_path,"r");
flock($file_stat,LOCK_EX);
$count = fread($file_stat,filesize($stat_file_path));
fclose($file_stat);
$count++;
$file_stat = fopen($stat_file_path,"w");
fwrite($file_stat,$count);
flock($file_stat,LOCK_UN);
fclose($file_stat);
echo($count);
exit();
}
</script>

get.php
PHP:
<?php 
$file = "pictures/".$_GET['filename'].".jpg";
header('Content-Description: File Transfer');
header('Content-Type: image/jpeg');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
?>



Счетчик работает, но вот вопрос: если в диалоге загрузки файла пользователь откажется от загрузки, счетчик все равно засчитает загрузку. Т.е. фактически считаются нажатия на кнопку “Download”.
Нужно каким-то образом узнать закачал ли юзер файл и инкрементировать счетчик только в этом случае.

Пытался как-нибудь с помощью значений, возвращаемых функций PHP( readfile($file) и др.) отслеживать был ли отдан файл, менять последовательность(сначала выдача ссылки на загрузку, а потом инкрементирование, но инкрементация выполнялась без ожидания окончания выполнения выдачи файла) и даже искал название отданных файлов в access.log файле статистики Apache сервера, но нажал ли узер «Сохранить», нажал ли юзер «Отменить», в access.log файлы одинаково фиксируются как отданные. Пока ничего не получилось.

Буду рад любым вашим идеям!
Заранее благодарен
 
N

nws

[заргузить] -> ajax -> upload.php -> результат в html

//upload.php
if ( move_uploaded_file($file) ) {
//$upload_count++
// еще какая-то логика
$message = 'ok';
} else {
$message = 'goliak';
}
 
I

IRinat

[заргузить] -> ajax -> upload.php -> результат в html

//upload.php
if ( move_uploaded_file($file) ) {
//$upload_count++
// еще какая-то логика
$message = 'ok';
} else {
$message = 'goliak';
}

В upload.php нужно передавать имя файла на локальном компьютере, так?
А как можно узнать под каким именем юзер сохранил у себя файл и передать это имя в upload.php для загрузки на сервер?
 
N

nws

В upload.php нужно передавать имя файла на локальном компьютере, так?
А как можно узнать под каким именем юзер сохранил у себя файл и передать это имя в upload.php для загрузки на сервер?

Код:
<form method="post" enctype="multipart/form-data">
<input type="file" />
<input type="submit" name="btn_upload" />
</form>

if ( $_POST['btn_upload'] ) {
echo '<pre>';
# в одном из элементов массива будет имя файла юзера на локальном ПК в момент выбора
print_r($_FILES[]); 
echo '</pre>';
}
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!