Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: разработка для Web > кириллица в cookies


Автор: Deft 30.12.2008, 15:05
устанавливаю куки через Set-Cookie
читаю так:
Код

 $buffer=$ENV{'HTTP_COOKIE'};
@pairs = split(/; /, $buffer);
foreach $pair (@pairs) {
  ($name, $value) = split(/=/, $pair);$value =~ tr/+/ /;
  $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  $in{$name} = $value;}


работает только с латиницей, что поменять чтоб и с кириллицей пахало? 
з.ы. темы на форуме по кукисам читал, но как в данном случае добавить кириллицу не нашел...

Автор: ginnie 30.12.2008, 15:18
Deft, а какие именно проблемы с кириллицей? Можно описать подробнее, а то угадывать тяжеловато.

Автор: Deft 30.12.2008, 15:36
ну к примеру записываем "тест" читаем "тест" ...

Автор: ginnie 30.12.2008, 16:12
Deft, рекомендую сохранять данные в cookie в uft8. Если не хотите, смотрите в направлении модуля Encode, Вам надо конвертировать текст из unicode в нужную кодировку (вероятно, cp1251).

Автор: Deft 30.12.2008, 16:36
utf8 мне не подходит, т.к. еще идет работа с mysql и туда мне надо в 1251 сохранять...
а что за модуль encode и как его конкретно применить ? а то я не особо разбираюсь(
з.ы. как я понял его надо ставить отдельно? просто работаю с университетским сервером (курсовую делаю) и если этот модуь не ставится по умолчанию с перлом а является каким-то специфичным то врятли он установлен..

Автор: ginnie 31.12.2008, 14:21
Deft, работать с cookie в utf8, а в БД сохранять в cp1251 проблемы не составляет: клиент mysql умеет перекодировать (надо только указать кодировку при соединении), правда, не во всех версиях. Для перекодировки в скрипте можно использовать функцию Encode::from_to(). Модуль http://search.cpan.org/~dankogai/Encode-2.26/Encode.pm на Вашем сервере с большой вероятностью установлен - теперь он ставится в составе дистрибутива. Проверить это не сложно - добавьте use Encode в скрипт и запустите на выполнение.

Автор: tolkien 31.12.2008, 15:02
Кодируй значения кук url кодингом.
Тем более у тебя всравно обратный процесс декодинга уже имеется.

Автор: Deft 2.1.2009, 08:32
Цитата(tolkien @  31.12.2008,  15:02 Найти цитируемый пост)
Кодируй значения кук url кодингом.

что это значит? что за урл кодинг?


ginnie, 

для проверки делаю:
Код

   print $in{'log'}; // начальное значение - тест
   $lgnenc=encode("utf8",$in{'log'});
   print $lgnenc;  //в utf8  - ГІГҐГ±ГІ
   $lgnenc1=$lgnenc;
   from_to($lgnenc1, "utf8", "cp1250");
   print $lgnenc1; // пустота


в чем ошибка?

з.ы если заменить
Код

 from_to($lgnenc1, "utf8", "cp1250");

на
Код


$lgnenc1=encode("cp1251", decode("utf8", $lgnenc1));


то на выходе получаем "????"

Автор: tolkien 2.1.2009, 11:34
Вот у тебя строчка
Код

$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

Она декодирует. А тебе надо наоборот еще и кодировать когда сохраняешь значения куки. Т.е русские буквы A, Б, В переводить в псолед. вида %A0, %A1, %A2. 

Автор: Deft 2.1.2009, 12:18
погуглил чутка, наткнулся на
Код

$str =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg;


оно?  декодирующая функция там вроде как у меня была.. только с seg на конце вместо eg

только помоему что в декодирующей функции что в кодирующей используется одна латиница...

Автор: tolkien 2.1.2009, 14:13
Пример

Код


my $url = 'http://www.infanata.org/index.php?do=search&subaction=search&story=%C0%ED%E0%EB%E8%F2%E8%F7%E5%F1%EA%E0%FF%20%E3%E5%EE%EC%E5%F2%F0%E8%FF%20%E2%20%EF%F0%E8%EC%E5%F0%E0%F5%20%E8%20%E7%E0%E4%E0%F7%E0%F5';
print "before e2s\n",$url,"\n";
print "after e2s\n",e2s(\$url),"\n";
print "after s2e\n",s2e(\$url),"\n";
print "after e2s\n",e2s(\$url),"\n";

#урл декодирование
sub e2s
{
  my ($s) = @_;
  
  if (${$s})
  {
    my $p1 = 0;
    
    while( ($p1 = index(${$s}, '%', $p1)) != -1)
    {
      substr(${$s}, $p1, 3, chr(hex(substr(${$s}, $p1 + 1, 2))));
      $p1++;
    }
  }

  return ${$s};
}


#урл кодирование
sub s2e
{
  my ($s) = @_;

  if (${$s})
  {
    for (my $i = 0; $i < length(${$s}); )
    {
      my $n = ord( substr(${$s}, $i, 1) );
     
      if (($n >= 48 && $n <= 57) || ($n >= 97 && $n <= 122) || ($n >= 65 && $n <= 90))
      {
        $i++;
      }
      else
      {
        my $e = sprintf("%%%02X",$n);
        substr(${$s}, $i, 1, $e);
        $i += length($e);
      }
    }
  }
  
  return ${$s};
}

Автор: Deft 10.1.2009, 06:35
все оказалось проще:
подключил
Код

use URI::Escape;

затем использовал
uri_escape(); и uri_unescape();

Автор: Usmanec 24.2.2009, 16:19
Вобщето нецелесообразно гонять большое количество данных в заголовках запроса. Проще пользователю присвоить идентификатор и все хранить на сервере.
А вобще перед тем как установить кукис нужно преобразовать недопустимые символы.

Код

sub setcookie(%){
    my(%cook)=@_;
    my(@cook,$name,$value);
    foreach $name (keys %cook){
         $value=$cook{$name};
         $value=~s/([=\+&%\/\\\|\0-\x1f\x80-\xff])/sprintf("%%%02X",unpack('C',$1))/eg;
         $value=~y/ /+/;
         $name=~s/([=\+&%\/\\\|\0-\x1f\x80-\xff])/sprintf("%%%02X",unpack('C',$1))/eg;
         $name=~y/ /+/;
         push(@cook,"$name=$value");
         }
    return join('; ',@cook);
    }
print setcookie(
                               'Параметр1' => 'Значение1',
                               'Параметр2' => 'Значение2',
                               'ПараметрN' => 'ЗначениеN',
                               'Name'      => 'V a l u e',
                               )."\n";

В результате получим следующую строку
%CF%E0%F0%E0%EC%E5%F2%F01=%C7%ED%E0%F7%E5%ED%E8%E51; %CF%E0%F0%E0%EC%E5%F2%F02=%C7%ED%E0%F7%E5%ED%E8%E52; Name=V+a+l+u+e; %CF%E0%F0%E0%EC%E5%F2%F0N=%C7%ED%E0%F7%E5%ED%E8%E5N

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)