Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Повторная запись в гостевую книгу при обновлении, как избавиться? 
V
    Опции темы
Leshik
Дата 6.9.2007, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 1.10.2006

Репутация: нет
Всего: нет



Здрасте =)
Помогите пожалуйста.
Написал скрипт простейшей гостевой книги(практически списано из "Изучаем Perl")/
Код

#! perl -w

use strict;
use CGI qw/:standard/;
use CGI::Carp qw( fatalsToBrowser );
use Fcntl qw/:flock/;

#скрипт гостевой книги
sub bail{                          
    my $error = "@_";
    print p(h4("Error:"), $error);
    print end_html;
    die $error;
}

my( 
    $message_file,
    $title,
    $obj,
    $mes,
    @arr,
    $name);

$message_file = "tmp/guestbook";
$title = "Гостевая книга";
$obj = CGI->new();

print header(
    -type => 'text/html',
    -charset => 'windows-1251'),
    start_html($title), h3($title);

    if (param("message")) {
        $obj->param("date", scalar localtime);
        $obj->param("addr", $ENV{REMOTE_ADDR});
            if (!param("name")) {
                $name = "Анонимно";
                $obj->param("name", $name);
            }
        @arr = ($obj)
}

open (FILE_BOOK, "+< $message_file") or bail("cannot open $message_file: $!");
flock(FILE_BOOK, LOCK_EX) or bail("cannot flock $message_file: $!");
    
    while (!eof(FILE_BOOK)) {
        $mes = CGI->new(\*FILE_BOOK);
        push @arr, $mes;
    }

seek(FILE_BOOK, 0, 0) or bail ("cannot rewind $message_file: $!");
    foreach $mes (@arr) {
        $mes->save(\*FILE_BOOK);
    };
close(FILE_BOOK);

print hr(), start_form(),
    p("Ваше имя:", $obj->textfield(
    -NAME => "name",
    -OVERRIDE => 1)),
    p("Ваше сообщение:"), 
    $obj->textarea(
    -NAME => "message",
    -OVERRIDE => 1,
    -ROWS => 10,
    -COLUMNS => 40,
    -MAXLENGTH => 10),
    p(submit(
    -NAME =>"Отправить",
    -onClick =>), reset("Очистить")),
    end_form();
print hr(), h4("Предыдущие сообщения:");
    foreach $mes (@arr) {
        printf "%s\t[%s]:\t%s", $mes->param("date"), $mes->param("name"), $mes->param("message");
        print br();
    }
print end_html();

После того, как я ввожу имя и сообщение и жму на кнопку "отправить", если я обновляю страницу, то те же самые данные записываются ещё раз. И так всё время.
Подскажите, пожалуйста, как от этого можно избавиться.

Прошу извинить меня, за размещение не в ветке "CGI-программирование"( немного промахнулся smile)

Это сообщение отредактировал(а) Leshik - 6.9.2007, 18:37
PM MAIL   Вверх
maxim1000
Дата 6.9.2007, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: нет
Всего: 110



Perl'а я не знаю, но сталкивался с подобной ситуацией
решил её так:
ответом на запрос является перенаправление на страницу completed.html (к примеру), на которой написано что-то в духе "выполнено"
даже если пользователь будет обновлять её, ему просто каждый раз будут писать "выполнено"


--------------------
qqq
PM WWW   Вверх
Leshik
Дата 6.9.2007, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 1.10.2006

Репутация: нет
Всего: нет



Спасибо.
О таком решении я тоже задумывался, но всё же может быть есть ещё какой-нибудь способ?
PM MAIL   Вверх
comtat
Дата 6.9.2007, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1310
Регистрация: 2.5.2006
Где: Россия, Казань

Репутация: нет
Всего: 71



Цитата(Leshik @  6.9.2007,  21:48 Найти цитируемый пост)
но всё же может быть есть ещё какой-нибудь способ? 

ИМХО редирект на другую страницу самый правильный вариант



--------------------
Рожденный в СССР !!!
ExtJS - мой фреймворк 
PM   Вверх
StealtH
Дата 6.9.2007, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 124
Регистрация: 16.9.2004

Репутация: нет
Всего: нет



Имхо, из предложенного выше - самый идельный способ, сам им пользуюсь при любом запросе методом POST.
Как вариант, попробуй в базу писать md5 хеш поста, и потом при новом посте искать по этому ключу, если не найдено - добавляешь пост, если найдено - пишешь об этом пользователю или редиректишь на главную страницу.
PM MAIL   Вверх
Leshik
Дата 6.9.2007, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 1.10.2006

Репутация: нет
Всего: нет



Цитата(StealtH @  6.9.2007,  23:11 Найти цитируемый пост)
Как вариант, попробуй в базу писать md5 хеш поста

А не могли бы вы обьяснить как это сделать или где про это можно почитать.
Спасибо

PM MAIL   Вверх
StealtH
Дата 7.9.2007, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 124
Регистрация: 16.9.2004

Репутация: нет
Всего: нет



Цитата(Leshik @ 6.9.2007,  23:27)
Цитата(StealtH @  6.9.2007,  23:11 Найти цитируемый пост)
Как вариант, попробуй в базу писать md5 хеш поста

А не могли бы вы обьяснить как это сделать или где про это можно почитать.
Спасибо

Запросто ! 

man Digest::MD5

Там даже примеры есть. 

Если вкратце, то делаешь хэш(md5_hex($post)) и пишешь его в отдельный файл, потом при добавлении поста формируешь md5-сумму поста и ищешь подобную в файле с хэшами. 


Код


#!/usr/bin/perl

use strict;

..................................

my $hash = md5_hex($FORM{'post'});
open FILE, 'hashes';
chomp(my @hashes = <FILE>);
my $flag = 0;
for(0..$#hashes)}{

    if($hash eq $hashes[$_]){
         $flag = 1;
         last;
    }
}

if (!$flag){
    open FILE, ">>hashes";
    print FILE $hash, "\n";
} else {
    &message('Duplicate of record');
}





Примерно так, но такой подход не есть зергуд в плане быстродействия и ресурсов, особенно когда количество записей в гесте будет больше 5-6 тысяч.
PM MAIL   Вверх
SHAmanovi4
Дата 7.9.2007, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 63
Регистрация: 13.9.2006
Где: почти мск

Репутация: нет
Всего: нет



А я делаю self-redirect. То есть, перенаправляю на ту же страницу. Если нужно вывести сообщение, то делаю так:

Код

print qq(Location: $ENV{HTTP_REFERER}&ok=1\n\n);

А при выводе формы и гостевой палю, есть ли этот параметр.

Код

if($ENV{ok})
{
print "<h2 class='ok'>Ваше сообщение добавлено</h2>";
}


Это сообщение отредактировал(а) SHAmanovi4 - 7.9.2007, 14:30
PM WWW ICQ   Вверх
Leshik
Дата 7.9.2007, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 1.10.2006

Репутация: нет
Всего: нет



Всем спасибо  smile , буду пробовать.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0741 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.