Forum Webscript.Ru
Программирование => Perl => Тема начата: frank258 от 10 Апреля 2007, 21:04:24
-
Здравствуйте
Помогите решить проблему - есть на сайте форма для отправки сообщений, обрабатывает ее скрипт на perl, но в тексте приходящих с сайта сообщений русские буквы не отображаются, нормально отправляется только латиница. Подскажите, где в скрипте что нужно исправить. к сожалению весь скрипт не влез.
@recipients = &fill_recipients(@referers);
@valid_ENV = (\'REMOTE_HOST\',\'REMOTE_ADDR\',\'REMOTE_USER\',\'HTTP_USER_AGENT\');
# Check Referring URL
&check_url;
# Retrieve Date
&get_date;
# Parse Form Contents
&parse_form;
# Check Required Fields
&check_required;
# Send E-Mail
&send_mail;
# Return HTML Page or Redirect User
&return_html;
# NOTE rev1.91: This function is no longer intended to stop abuse, that #
# functionality is now embedded in the checks made on @recipients and the #
# recipient form field. #
sub check_url {
# Localize the check_referer flag which determines if user is valid. #
local($check_referer) = 0;
# If a referring URL was specified, for each valid referer, make sure #
# that a valid referring URL was passed to FormMail. #
if ($ENV{\'HTTP_REFERER\'}) {
foreach $referer (@referers) {
if ($ENV{\'HTTP_REFERER\'} =~ m|https?://([^/]*)$referer|i) {
$check_referer = 1;
last;
}
}
}
else {
$check_referer = 1;
}
# If the HTTP_REFERER was invalid, send back an error. #
if ($check_referer != 1) { &error(\'bad_referer\') }
}
sub get_date {
# Define arrays for the day of the week and month of the year. #
@days = (\'Воскресенье\',\'Понедельник\',\'Вторник\',\'Среду\',
\'Четверг\',\'Пятницу\',\'Субботу\');
@months = (\'Января\',\'Февраля\',\'Марта\',\'Апреля\',\'Мая\',\'Июня\',\'Июля\',
\'Августа\',\'Сентября\',\'Октября\',\'Ноября\',\'Декабря\');
# Get the current time and format the hour, minutes and seconds. Add #
# 1900 to the year to get the full 4 digit year. #
($sec,$min,$hour,$mday,$mon,$year,$wday) = (localtime(time))[0,1,2,3,4,5,6];
$time = sprintf("%02d:%02d:%02d",$hour,$min,$sec);
$year += 1900;
# Format the date. #
$date = "$days[$wday], $mday $months[$mon] $year года, в $time - по Моск.";
}
sub parse_form {
# Define the configuration associative array. #
%Config = (\'recipient\',\'\', \'subject\',\'\',
\'email\',\'\', \'realname\',\'\',
\'redirect\',\'\', \'bgcolor\',\'\',
\'background\',\'\', \'link_color\',\'\',
\'vlink_color\',\'\', \'text_color\',\'\',
\'alink_color\',\'\', \'title\',\'\',
\'sort\',\'\', \'print_config\',\'\',
\'required\',\'\', \'env_report\',\'\',
\'return_link_title\',\'\', \'return_link_url\',\'\',
\'print_blank_fields\',\'\', \'missing_fields_redirect\',\'\');
# Determine the form\'s REQUEST_METHOD (GET or POST) and split the form #
# fields up into their name-value pairs. If the REQUEST_METHOD was #
# not GET or POST, send an error. #
if ($ENV{\'REQUEST_METHOD\'} eq \'GET\') {
# Split the name-value pairs
@pairs = split(/&/, $ENV{\'QUERY_STRING\'});
}
elsif ($ENV{\'REQUEST_METHOD\'} eq \'POST\') {
# Get the input
read(STDIN, $buffer, $ENV{\'CONTENT_LENGTH\'});
# Split the name-value pairs
@pairs = split(/&/, $buffer);
}
else {
&error(\'request_method\');
}
# For each name-value pair: #
foreach $pair (@pairs) {
# Split the pair up into individual variables. #
local($name, $value) = split(/=/, $pair);
# Decode the form encoding on the name and value variables. #
# v1.92: remove null bytes #
$name =~ tr/+/ /;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ tr/\\0//d;
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ tr/\\0//d;
# If the field name has been specified in the %Config array, it will #
# return a 1 for defined($Config{$name}}) and we should associate #
# this value with the appropriate configuration variable. If this #
# is not a configuration form field, put it into the associative #
# array %Form, appending the value with a \', \' if there is already a #
# value present. We also save the order of the form fields in the #
# @Field_Order array so we can use this order for the generic sort. #
if (defined($Config{$name})) {
$Config{$name} = $value;
}
else {
if ($Form{$name} ne \'\') {
$Form{$name} = "$Form{$name}, $value";
}
else {
push(@Field_Order,$name);
$Form{$name} = $value;
}
}
}
# The next six lines remove any extra spaces or new lines from the #
# configuration variables, which may have been caused if your editor #
# wraps lines after a certain length or if you used spaces between field #
# names or environment variables. #
$Config{\'required\'} =~ s/(\\s+|\\n)?,(\\s+|\\n)?/,/g;
$Config{\'required\'} =~ s/(\\s+)?\\n+(\\s+)?//g;
$Config{\'env_report\'} =~ s/(\\s+|\\n)?,(\\s+|\\n)?/,/g;
$Config{\'env_report\'} =~ s/(\\s+)?\\n+(\\s+)?//g;
$Config{\'print_config\'} =~ s/(\\s+|\\n)?,(\\s+|\\n)?/,/g;
$Config{\'print_config\'} =~ s/(\\s+)?\\n+(\\s+)?//g;
# Split the configuration variables into individual field names. #
@Required = split(/,/,$Config{\'required\'});
@Env_Report = split(/,/,$Config{\'env_report\'});
@Print_Config = split(/,/,$Config{\'print_config\'});
# ACCESS CONTROL FIX: Only allow ENV variables in @valid_ENV in #
# @Env_Report for security reasons. #
foreach $env_item (@Env_Report) {
foreach $valid_item (@valid_ENV) {
if ( $env_item eq $valid_item ) { push(@temp_array, $env_item) }
}
}
@Env_Report = @temp_array;
}
sub check_required {
# Localize the variables used in this subroutine. #
local($require, @error);
# The following insures that there were no newlines in any fields which #
# will be used in the header. #
if ($Config{\'subject\'} =~ /(\\n|\\r)/m || $Config{\'email\'} =~ /(\\n|\\r)/m ||
$Config{\'realname\'} =~ /(\\n|\\r)/m || $Config{\'recipient\'} =~ /(\\n|\\r)/m) {
&error(\'invalid_headers\');
}
if (!$Config{\'recipient\'}) {
if (!defined(%Form)) { &error(\'bad_referer\') }
else { &error(\'no_recipient\') }
}
else {
# This block of code requires that the recipient address end with #
# a valid domain or e-mail address as defined in @recipients. #
$valid_recipient = 0;
foreach $send_to (split(/,/,$Config{\'recipient\'})) {
foreach $recipient (@recipients) {
if ($send_to =~ /$recipient$/i) {
push(@send_to,$send_to); last;
}
}
}
if ($#send_to < 0) { &error(\'no_recipient\') }
$Config{\'recipient\'} = join(\',\',@send_to);
}
# For each require field defined in the form: #
foreach $require (@Required) {
# If the required field is the email field, the syntax of the email #
# address if checked to make sure it passes a valid syntax. #
if ($require eq \'email\' && !&check_email($Config{$require})) {
push(@error,$require);
}
# Otherwise, if the required field is a configuration field and it #
# has no value or has been filled in with a space, send an error. #
elsif (defined($Config{$require})) {
if ($Config{$require} eq \'\') { push(@error,$require); }
}
# If it is a regular form field which has not been filled in or #
# filled in with a space, flag it as an error field. #
elsif (!defined($Form{$require}) || $Form{$require} eq \'\') {
push(@error,$require);
}
}
# If any error fields have been found, send error message to the user. #
if (@error) { &error(\'missing_fields\', @error) }
}
sub return_html {
# Local variables used in this subroutine initialized. #
local($key,$sort_order,$sorted_field);
# Now that we have finished using form values for any e-mail related #
# reasons, we will convert all of the form fields and config values #
# to remove any cross-site scripting security holes. #
local($field);
foreach $field (keys %Config) {
$safeConfig{$field} = &clean_html($Config{$field});
}
foreach $field (keys %Form) {
$Form{$field} = &clean_html($Form{$field});
}
# If redirect option is used, print the redirectional location header. #
if ($Config{\'redirect\'}) {
print "Location: $safeConfig{\'redirect\'}\\n\\n";
}
# Otherwise, begin printing the response page. #
else {
# Print HTTP header and opening HTML tags. #
print "Content-type: text/html\\n\\n";
print "\\n \\n";
# Print out title of page #
if ($Config{\'title\'}) { print "$safeConfig{\'title\'}\\n" }
else { print "Спасибо!\\n" }
print " \\n
# Get Body Tag Attributes #
&body_attributes;
# Close Body Tag #
print ">\\n \\n";
-
Вот еще один скрипт на php, тоже работает но не отправляет кириллицу, может знает кто нибудь
что в нем надо исправить.
}
function complete_mail() {
// $_POST[\'title\'] содержит данные из поля "Тема", trim() - убираем все лишние пробелы и переносы строк, htmlspecialchars() - преобразует специальные символы в HTML сущности, будем считать для того, чтобы простейшие попытки взломать наш сайт обломались, ну и substr($_POST[\'title\'], 0, 1000) - урезаем текст до 1000 символов. Для переменных $_POST[\'mess\'], $_POST[\'name\'], $_POST[\'tel\'], $_POST[\'email\'] все аналогично
$_POST[\'title\'] = substr(htmlspecialchars(trim($_POST[\'title\'])), 0, 1000);
$_POST[\'mess\'] = substr(htmlspecialchars(trim($_POST[\'mess\'])), 0, 1000000);
$_POST[\'name\'] = substr(htmlspecialchars(trim($_POST[\'name\'])), 0, 30);
$_POST[\'fam\'] = substr(htmlspecialchars(trim($_POST[\'fam\'])), 0, 30);
$_POST[\'email\'] = substr(htmlspecialchars(trim($_POST[\'email\'])), 0, 50);
// если не заполнено поле "Имя" - показываем ошибку 0
if (empty($_POST[\'name\']))
output_err(0);
// если не заполнено поле "Фамилия" - показываем ошибку 1
if (empty($_POST[\'fam\']))
output_err(1);
// если неправильно заполнено поле email - показываем ошибку 2
if(!preg_match("/[0-9a-z_]+@[0-9a-z_^\\.]+\\.[a-z]{2,3}/i", $_POST[\'email\']))
output_err(2);
// если не заполнено поле "Сообщение" - показываем ошибку 3
if(empty($_POST[\'mess\']))
output_err(3);
// создаем наше сообщение
$mess = \'
Имя отправителя:\'.$_POST[\'name\'].\'
Фамилия отправителя:\'.$_POST[\'fam\'].\'
Контактный email:\'.$_POST[\'email\'].\'
\'.$_POST[\'mess\'];
// $to - кому отправляем
$to = ;
// $from - от кого
$from=\'test@test.ru\';
mail($to, $_POST[\'title\'], $mess, "From:".$from);
$mailheaders = "Content-Type: text/plain; charset=Windows-1251\\n";
$mailheaders .= "From: $email\\n";
echo \'Спасибо! Ваше письмо отправлено.\';
}
function output_err($num)
{
$err[0] = \'ОШИБКА! Не введено имя.\';
$err[1] = \'ОШИБКА! Не введено имя.\';
$err[2] = \'ОШИБКА! Неверно введен e-mail.\';
$err[3] = \'ОШИБКА! Не введено сообщение.\';
echo \'\'.$err[$num].\'
\';
show_form();
exit();
}
if (!empty($_POST[\'submit\'])) complete_mail();
else show_form();
?>
-
frank258:
Подскажите, где в скрипте что нужно исправить. к сожалению весь скрипт не влез.
Не к сожалению, а к счастью, никто этот листинг не будет читать. Если не умеешь писать на Perl, платишь денюшку, и тебе пишут. Если умеешь, то прописываешь правильно хедеры, в письме текст в правильной кодировке указанной в хедерах. Тема сообщения кодируется к примеру таким образом:
use MIME::Base64;
my $subject = "тема письма"
$subject = "=?WINDOWS-1251?B?".substr(encode_base64($subject),0,-1)."?=";
-
А сколько стоит исправить скрипт что бы он нормально отправлял кириллицу?
-
Вот сюда напиши теребования
http://forums.webscript.ru/forumdisplay.php?s=&forumid=22
-
Все! сам разобрался с PHP надо в код скрипта добавить
$mailheaders .= "Content-Type: text/plain; charset="._CHARSET."\\n\\n";
И никакую денюшку за это платить не надо, а ламеру не грех было и подсказать - не все изучают программирование с 5 класса.
-
Во первых, это раздел Perl.
Во вторых, тему нужно составлять согласно RFC.
В третьих, тут все работают, а твоя задача не совсем тривиальна, нужно разобраться в чужом коде и сделать исправления.
Ну и наконец:
NeoNox:
прописываешь правильно хедеры, в письме текст в правильной кодировке указанной в хедерах.
;)