Вопрос

По-видимому, кодирование электронных писем на японском языке является несколько сложной задачей, которую я постепенно открываю для себя сам.На случай, если найдутся какие-либо эксперты (подойдут даже те, у кого ограниченный опыт), могу ли я, пожалуйста, дать несколько рекомендаций относительно того, как это сделать, как это протестировать и как это проверить?

Имейте в виду, что я никогда и близко не подходил к Японии, просто продукт, который я разрабатываю, используется там, среди прочих мест.

Что (я думаю) Я пока знаю следующее:
- Электронные письма на японском языке должны быть закодированы в стандарте ISO-2022-JP, кодовая страница японской JIS 50220 или, возможно, кодовая страница SHIFT_JIS 932
- Кодировка передачи электронной почты должна быть установлена на Base64 для обычного текста и 7Bit для Html
- Тема электронного письма должна быть закодирована отдельно и начинаться с "=?ISO-2022-JP?B?" (не знаю, что это должно означать).Я попробовал закодировать тему с помощью

"=?ISO-2022-JP?B?" + Convert.ToBase64String(Encoding.Unicode.GetBytes(subject))

который в основном выдает закодированную строку, как и ожидалось, но она не представляется в виде какого-либо текста на японском языке в почтовой программе
- Я тестировал в Outlook 2003, Outlook Express и GMail

Мы были бы очень признательны за любую помощь


Хорошо, итак, чтобы опубликовать короткое обновление, благодаря двум полезным ответам мне удалось получить правильный формат и кодировку.Теперь Outlook выдает что-то похожее на правильную тему:
=?iso-2022-jp?B?6 Japanese test に各々の視点で語ってもらった。 6相当の防水?=

Однако точно такое же электронное письмо в Outlook Express содержит тему, подобную этой:
=?iso-2022-jp?B?6 Japanese test 縺ォ蜷・・・隕也せ縺ァ隱槭▲縺ヲ繧ゅi縺」縺溘・ 6逶ク蠖薙・髦イ豌エ?=

Кроме того, при просмотре в режиме "Входящие" в Outlook Express тема письма выглядит еще более странной, например, так:
=?iso-2022-jp?B?6 Japanese test ??????????????? 6???????=

Gmail, похоже, работает аналогично Outlook, что выглядит корректно.

У меня просто не укладывается это в голове.

Это было полезно?

Решение

Я имею дело с японскими кодировками почти 20 лет и поэтому могу посочувствовать вашим трудностям.Веб-сайты, над которыми я работал, ежедневно рассылают сотни электронных писем японским клиентам, чтобы я мог поделиться с вами тем, что сработало у нас.

  • Прежде всего, не используйте Shift-JIS.Я лично получаю тонны электронных писем на японском языке, и почти никогда они не кодируются с помощью Shift-JIS.Я думаю, что старая (около Win 98?) версия Outlook Express кодировала исходящую почту с помощью Shift-JIS, но в настоящее время вы ее просто не видите.

  • Как вы уже поняли, вам нужно использовать ISO-2022-JP в качестве кодировки по крайней мере для всего, что содержится в заголовке письма.Это включает в себя тему, строку "Кому" и строку CC.UTF-8 также будет работать в большинстве случаев, но это не будет работать с Yahoo Japan mail, и, как вы можете себе представить, многие японские пользователи используют Yahoo Japan mail.

  • Вы можете использовать UTF-8 в теле электронного письма, но рекомендуется, чтобы base64 кодировал японский текст в кодировке UTF-8 и помещал его в тело вместо необработанного текста в формате UTF-8.Однако на практике я считаю, что необработанный текст в формате UTF-8 в наши дни будет отлично работать для тела электронного письма.

  • Как я упоминал выше, вам необходимо, по крайней мере, протестировать Outlook (Exchange), Outlook Express (IMAP / POP3) и Yahoo Japan web mail.Yahoo Japan - самая сложная, потому что я считаю, что они используют EUC для кодирования своих веб-страниц, и поэтому вам нужно следовать правильным стандартам для ваших электронных писем, иначе они не будут работать (ISO-2022-JP - стандарт для отправки электронных писем на японском языке).

  • Кроме того, ваша тема письма не должна превышать 75 символов в строке.То есть 75 символов после вы закодировали в ISO-2022-JP и base64, а не 75 символов до преобразования.Если количество символов превышает 75, вам необходимо разбить закодированную тему на несколько строк, начиная с "=?iso-2022-jp?B?" и заканчивая "?=" в каждой строке.Если вы этого не сделаете, ваша тема может быть сокращена (в зависимости от программы чтения электронной почты, а также от содержания вашего текста темы).Согласно RFC 2047:

"Длина "закодированного слова" не может превышать 75 символов, включая "кодировку", "кодировку", "закодированный текст" и разделители.Если желательно закодировать больше текста, чем поместится в "кодированном слове" из 75 символов, можно использовать несколько "кодированных слов" (разделенных ПРОБЕЛОМ CRLF)."

  • Вот несколько примеров PHP-кода для кодирования темы:

 // Convert Japanese subject to ISO-2022-JP (JIS is essentially ISO-2022-JP)

 $subject = mb_convert_encoding ($subject, "JIS", "SJIS");

 // Now, base64 encode the subject

 $subject = base64_encode ($subject);

 // Add the encoding markers to the subject

 $subject = "=?iso-2022-jp?B?" . $subject . "?=";

 // Now, $subject can be placed as-is into the raw mail header.
  • Смотрите RFC 2047 для получения полного описания того, как закодировать заголовок вашего электронного письма.

Другие советы

Проверить http://en.wikipedia.org/wiki/MIME#Encoded-Word для получения описания того, как кодировать поля заголовка в сообщениях, совместимых с MIME.Кажется, вам не хватает “?=” в конце вашей темы.

=?ISO-2022-JP?B?ТЕКСТТЕКСТ...

ISO_2022-JP означает, что строка закодирована в кодовой странице ISO-2022-JP (например.не в Юникоде) B означает, что строка имеет кодировку bese64

В вашем примере вы должны просто указать свою строку в ISO-2022-JP вместо Unicode.

У меня есть некоторый опыт составления и отправки электронной почты на японском языке ... Обычно вы должны остерегаться того, какая кодировка используется для операционной системы и как вы храните свои японские строки!Мои почтовые объекты обычно кодируются следующим образом:

    string s = "V‚µ‚¢ŠwK–@‚Ì‚²’ñˆÄ"; // Our japanese are shift-jis encoded, so it appears like garbled
    MailMessage message = new MailMessage();
    message.BodyEncoding = Encoding.GetEncoding("iso-2022-jp");
    message.SubjectEncoding = Encoding.GetEncoding("iso-2022-jp");
    message.Subject = s.ToEncoding(Encoding.GetEncoding("Shift-Jis")); // Change the encoding to whatever your source is
    message.Body = s.ToEncoding(Encoding.GetEncoding("Shift-Jis")); // Change the encoding to whatever your source is

Тогда у меня есть метод расширения, в который выполняется преобразование для меня:

public static string ToEncoding(this string s, Encoding targetEncoding)
        {   
            return s == null ? null : targetEncoding.GetString(Encoding.GetEncoding(1252).GetBytes(s)); //1252 is the windows OS codepage            
        }

что-то вроде этого должно быть выполнено на python:


#!/usr/bin/python                                                                                                            
# -*- mode: python; coding: utf-8 -*-                                                                                        
import smtplib
from email.MIMEText import MIMEText
from email.Header import Header
from email.Utils import formatdate

def send_from_gmail( from_addr, to_addr, subject, body, password, encoding="iso-2022-jp" ):

    msg = MIMEText(body.encode(encoding), 'plain', encoding)
    msg['Subject'] = Header(subject.encode(encoding), encoding)
    msg['From'] = from_addr
    msg['To'] = to_addr
    msg['Date'] = formatdate()

    s = smtplib.SMTP('smtp.gmail.com', 587)
    s.ehlo(); s.starttls(); s.ehlo()

    s.login(from_addr, password)
    s.sendmail(from_addr, to_addr, msg.as_string())
    s.close()
    return "Sent mail to: %s" % to_addr



if __name__ == "__main__":
    import sys
    for n,item in enumerate(sys.argv):
        sys.argv[n] = sys.argv[n].decode("utf8")

    if len(sys.argv)==6:
        print send_from_gmail( sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5] )
    elif len(sys.argv)==7:
        print send_from_gmail( sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], encoding=sys.argv[6] )
    else:
        raise "SYNTAX: %s <from_addr> <to_addr> <subject> <body> <password> [encoding]"

**нагло украденный/адаптированный из:

http://mtokyo.blog9.fc2.com/blog-entry-127.html

Прежде всего, вы должны использовать:

Encoding.GetEncoding("ISO-2022-JP")

преобразовать строку темы в байты, которые будут обработаны Convert.ToBase64String().

=?ISO-2022-JP?B?TEXTTEXT ...?= сообщает принимающему почтовому клиенту, какая кодировка использовалась на стороне отправителя для преобразования японских "букв" в поток байтов.

В настоящее время вы используете UTF-16 для кодирования, но указываете ISO-2022-JP для декодирования.Я полагаю, это, очевидно, две разные кодировки, точно так же, как ISO-8859-1 отличается от Unicode (большинство расширенных символов западной Европы представлены одним байтом в ISO-XXX, но двумя байтами в Unicode).

Я не совсем уверен, что вы имеете в виду, говоря о том, что UTF-8 является гражданином второго сорта.Пока принимающий почтовый клиент понимает UTF-8 и способен преобразовать его в текущую японскую локаль, все в порядке.

<?php

function sendMail($to, $subject, $body, $from_email,$from_name)
 {
$headers  = "MIME-Version: 1.0 \n" ;
$headers .= "From: " .
       "".mb_encode_mimeheader (mb_convert_encoding($from_name,"ISO-2022-JP","AUTO")) ."" .
       "<".$from_email."> \n";
$headers .= "Reply-To: " .
       "".mb_encode_mimeheader (mb_convert_encoding($from_name,"ISO-2022-JP","AUTO")) ."" .
       "<".$from_email."> \n";


$headers .= "Content-Type: text/plain;charset=ISO-2022-JP \n";


/* Convert body to same encoding as stated
in Content-Type header above */

$body = mb_convert_encoding($body, "ISO-2022-JP","AUTO");

/* Mail, optional parameters. */
$sendmail_params  = "-f$from_email";

mb_language("ja");
$subject = mb_convert_encoding($subject, "ISO-2022-JP","AUTO");
$subject = mb_encode_mimeheader($subject);

$result = mail($to, $subject, $body, $headers, $sendmail_params);

return $result;
}

Внедрение японской кодировки в электронную почту произошло в JUNET (общенациональной сети на базе UUCP) в начале 90-х.

В то время был определен RFC1468.Если вы отправите RFC1468 обычным текстовым сообщением, проблем не возникнет.

Если вы хотите обрабатывать html-почту, RFC1468 бесполезен, за исключением частей заголовка.

Вот что я использую для отправки электронных писем на японском языке.Строка темы отлично смотрится в Outlook 2010, Gmail и на iPhone.

Encoding encoding = Encoding.GetEncoding("iso-2022-jp");
byte[] bytes  = encoding.GetBytes(subject);
string uuEncoded = Convert.ToBase64String(bytes);
subject = "=?iso-2022-jp?B?" + uuEncoded + "?=";

// not sure this is actually necessary...
mailMessage.SubjectEncoding = Encoding.GetEncoding("iso-2022-jp");
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top