Японская тема письма
По-видимому, кодирование японских писем является довольно сложной задачей, которую я постепенно открываю для себя. Если есть какие-либо эксперты (даже те, кто имеет ограниченный опыт), могу ли я дать некоторые рекомендации относительно того, как это сделать, как это проверить и как это проверить?
Имейте в виду, что я никогда не ступал нигде рядом с Японией, просто продукт, который я разрабатываю, используется там, среди других мест.
Что (я думаю) я знаю до сих пор следующее:
- Японские электронные письма должны быть закодированы в 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, что выглядит правильно.
Я просто не могу разобраться с этим.
9 ответов
Я работаю с японскими кодировками почти 20 лет и поэтому могу сочувствовать вашим трудностям. Веб-сайты, над которыми я работал, ежедневно отправляют сотни электронных писем японским клиентам, чтобы я мог поделиться с вами тем, что сработало для нас.
Прежде всего, не используйте Shift-JIS. Я лично получаю тонны японских писем, и почти никогда они не кодируются с помощью Shift-JIS. Я думаю, что старая (около Win 98?) Версия Outlook Express закодировала исходящую почту, используя Shift-JIS, но в настоящее время вы просто не видите ее.
Как вы уже поняли, вам нужно использовать ISO-2022-JP в качестве кодировки, по крайней мере, для всего, что идет в заголовке письма. Это включает тему, строку и строку CC. UTF-8 также будет работать в большинстве случаев, но он не будет работать с почтой Yahoo Japan, и, как вы можете себе представить, многие японские пользователи используют почту Yahoo Japan.
Вы можете использовать UTF-8 в теле письма, но рекомендуется, чтобы вы base64 кодировали японский текст в кодировке UTF-8 и помещали его в текст вместо необработанного текста UTF-8. Тем не менее, на практике, я считаю, что сырой текст UTF-8 в наши дни будет работать нормально для основной части письма.
Как я упоминал выше, вам необходимо как минимум протестировать Outlook (Exchange), Outlook Express (IMAP/POP3) и веб-почту Yahoo Japan. 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 для описания того, как кодировать поля заголовка в MIME-совместимых сообщениях. Вы, кажется, пропускаете "?=" В конце вашего предмета.
=?ISO-2022-JP? В? TEXTTEXT...
ISO_2022-JP означает, что строка закодирована в кодовой странице ISO-2022-JP (например, не Unicode) 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]"
** явно украдено / адаптировано из:
Вот что я использую для отправки японских писем. Тема выглядит хорошо в 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");
Прежде всего вы должны использовать:
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 бесполезен за исключением частей заголовка.