flask-mail遇到的编码问题

文章描述了在使用Flask-Mail模块发送邮件时遇到的Unicode编码错误,首先尝试修改`smtplib.py`中的`command_encoding`为`utf8`,但导致新的错误。最终解决方案是修改`policy.py`文件,将charset部分硬编码为`utf8`,从而成功发送含有非ASCII字符的邮件。
摘要由CSDN通过智能技术生成

首先碰到的下面的报错:

[2023-07-17 00:00:31,202] ERROR in app: Exception on /test [GET]
Traceback (most recent call last):
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask\app.py", line 2190, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask\app.py", line 1486, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask\app.py", line 1484, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask\app.py", line 1469, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Desktop\GitHub\personal-information-platform\app.py", line 46, in send_mail
    mail.send(msg)
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask_mail.py", line 491, in send
    with self.connect() as connection:
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask_mail.py", line 144, in __enter__
    self.host = self.configure_host()
                ^^^^^^^^^^^^^^^^^^^^^
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask_mail.py", line 163, in configure_host
    host.starttls()
  File "D:\software\Python311\Lib\smtplib.py", line 769, in starttls
    self.ehlo_or_helo_if_needed()
  File "D:\software\Python311\Lib\smtplib.py", line 611, in ehlo_or_helo_if_needed
    if not (200 <= self.ehlo()[0] <= 299):
                   ^^^^^^^^^^^
  File "D:\software\Python311\Lib\smtplib.py", line 451, in ehlo
    self.putcmd(self.ehlo_msg, name or self.local_hostname)
  File "D:\software\Python311\Lib\smtplib.py", line 378, in putcmd
    self.send(f'{s}{CRLF}')
  File "D:\software\Python311\Lib\smtplib.py", line 357, in send
    s = s.encode(self.command_encoding)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UnicodeEncodeError: 'ascii' codec can't encode characters in position 9-11: ordinal not in range(128)

遇到这个报错,第一时间修改上面错误堆栈中的command_encoding,如下:

    def send(self, s):
        """Send `s' to the server."""
        if self.debuglevel > 0:
            self._print_debug('send:', repr(s))
        if self.sock:
            if isinstance(s, str):
                # send is used by the 'data' command, where command_encoding
                # should not be used, but 'data' needs to convert the string to
                # binary itself anyway, so that's not a problem.
                s = s.encode(self.command_encoding)
            sys.audit("smtplib.send", self, s)

如上smtplib.py文件修改self.command_encoding,直接换成’utf8’就行,修改完以后,重启项目,就会报下面的错:

[2023-07-17 00:02:35,060] ERROR in app: Exception on /test [GET]
Traceback (most recent call last):
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask\app.py", line 2190, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask\app.py", line 1486, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask\app.py", line 1484, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask\app.py", line 1469, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Desktop\GitHub\personal-information-platform\app.py", line 46, in send_mail
    mail.send(msg)
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask_mail.py", line 492, in send
    message.send(connection)
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask_mail.py", line 427, in send
    connection.send(self)
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask_mail.py", line 190, in send
    message.as_bytes() if PY3 else message.as_string(),
    ^^^^^^^^^^^^^^^^^^
  File "D:\Desktop\GitHub\personal-information-platform\venv\Lib\site-packages\flask_mail.py", line 385, in as_bytes
    return self._message().as_bytes()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\software\Python311\Lib\email\message.py", line 208, in as_bytes
    g.flatten(self, unixfrom=unixfrom)
  File "D:\software\Python311\Lib\email\generator.py", line 116, in flatten
    self._write(msg)
  File "D:\software\Python311\Lib\email\generator.py", line 199, in _write
    self._write_headers(msg)
  File "D:\software\Python311\Lib\email\generator.py", line 422, in _write_headers
    self._fp.write(self.policy.fold_binary(h, v))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\software\Python311\Lib\email\policy.py", line 202, in fold_binary
    return folded.encode(charset, 'surrogateescape')
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UnicodeEncodeError: 'ascii' codec can't encode characters in position 56-58: ordinal not in range(128)

然后进去policy.py文件中修改下面信息

        folded = self._fold(name, value, refold_binary=self.cte_type=='7bit')
        charset = 'utf8' if self.utf8 else 'ascii'
        return folded.encode(charset, 'surrogateescape')

如上出问题的policy.py文件中,修改如上charset部分,删去charset = 'utf8' if self.utf8 else 'ascii'部分就行,然后就ok了,各种百度都找不到要的答案真的烦。记录一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值