【问题标题】:Nodemailer with Gmail and NodeJS带有 Gmail 和 NodeJS 的 Nodemailer
【发布时间】:2013-11-21 12:52:42
【问题描述】:

我尝试使用 nodemailer 来实现使用 NodeJS 的联系表单,但它仅适用于本地它不适用于远程服务器...

我的错误信息:

[website.fr-11 (out) 2013-11-09T15:40:26] { [AuthError: Invalid login - 534-5.7.14 <https://accounts.google.com/ContinueSignIn?sarp=1&scc=1&plt=AKgnsbvlX
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 V-dFQLgb7aRCYApxlOBuha5ESrQEbRXK0iVtOgBoYeARpm3cLZuUS_86kK7yPis7in3dGC
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 N1sqhr3D2IYxHAN3m7QLJGukwPSZVGyhz4nHUXv_ldo9QfqRydPhSvFp9lnev3YQryM5TX
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 XL1LZuJL7zCT5dywMVQyWqqg9_TCwbLonJnpezfBLvZwUyersknTP7L-VAAL6rhddMmp_r
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 A_5pRpA> Please log in via your web browser and then try again.
[website.fr-11 (out) 2013-11-09T15:40:26] 534-5.7.14 Learn more at https://support.google.com/mail/bin/answer.py?answer=787
[website.fr-11 (out) 2013-11-09T15:40:26] 534 5.7.14 54 fr4sm15630311wib.0 - gsmtp]
[website.fr-11 (out) 2013-11-09T15:40:26]   name: 'AuthError',
[website.fr-11 (out) 2013-11-09T15:40:26]   data: '534-5.7.14 <https://accounts.google.com/ContinueSignIn?sarp=1&scc=1&plt=AKgnsbvlX\r\n534-5.7.14 V-dFQLgb7aRCYApxlOBuha5ESrQEbRXK0iVtOgBoYeARpm3cLZuUS_86kK7yPis7in3dGC\r\n534-5.7.14 N1sqhr3D2IYxHAN3m7QLJGukwPSZVGyhz4nHUXv_ldo9QfqRydPhSvFp9lnev3YQryM5TX\r\n534-5.7.14 XL1LZuJL7zCT5dywMVQyWqqg9_TCwbLonJnpezfBLvZwUyersknTP7L-VAAL6rhddMmp_r\r\n534-5.7.14 A_5pRpA> Please log in via your web browser and then try again.\r\n534-5.7.14 Learn more at https://support.google.com/mail/bin/answer.py?answer=787\r\n534 5.7.14 54 fr4sm15630311wib.0 - gsmtp',
[website.fr-11 (out) 2013-11-09T15:40:26]   stage: 'auth' }

我的控制器:

exports.contact = function(req, res){
    var name = req.body.name;
    var from = req.body.from;
    var message = req.body.message;
    var to = '*******@gmail.com';
    var smtpTransport = nodemailer.createTransport("SMTP",{
        service: "Gmail",
        auth: {
            user: "******@gmail.com",
            pass: "*****"
        }
    });
    var mailOptions = {
        from: from,
        to: to, 
        subject: name+' | new message !',
        text: message
    }
    smtpTransport.sendMail(mailOptions, function(error, response){
        if(error){
            console.log(error);
        }else{
            res.redirect('/');
        }
    });
}

【问题讨论】:

  • google.com/accounts/DisplayUnlockCaptcha(为了可见性,由下面的好评论者发布)。只允许访问一次,让nodemailer自动登录,它会。
  • 在尝试使用 nodemailer 通过 gmail 发送邮件的所有方法后,以下设置对我有用..
  • 如果您好奇service 选项的来源(当我访问此页面时),隐藏文档页面是here。我称之为“隐藏”,因为它不在菜单中,除非你在那个确切的页面上。而且标志也不一样。

标签: javascript node.js nodemailer


【解决方案1】:

许多答案建议允许安全性较低的应用程序确实不是一个干净的解决方案。

您应该生成一个专用于此用途的应用密码

  1. 登录您的 Google 帐户
  2. 转到security
  3. 登录 Google 下启用两步验证
  4. 登录 Google 下点击应用密码
  5. 您现在将生成一个新密码。选择应用为Mail,选择设备为Other (Custom name)并命名。
  6. 保存应用密码

您现在可以使用此应用密码代替您的登录密码。

【讨论】:

    【解决方案2】:

    在生产环境中的 Vercel lambda 上运行时,我也遇到了 nodemailer 电子邮件发送问题。

    在我的情况下解决它的是等待 sendMail Promise 解决。

    我还添加了 nodemailer-smtp-transport 就像在这个帖子中建议的那样,但我认为这没有什么不同。

    这是我的全部功能:

    const nodemailer = require('nodemailer');
    const smtpTransport = require('nodemailer-smtp-transport');
    
    
    const transporter = nodemailer.createTransport(smtpTransport({
        service: 'gmail',
        auth: {
            user: '***@gmail.com',
            pass: process.env.SMTP_PASSWORD,
        },
    }));
    
    
    async function contact(req: any, res: any) {
        try {
            const response = await transporter.sendMail({
                from: '"*** <***gmail.com>', // sender address
                to: "***@gmail.com", // list of receivers
                subject: `***`, // Subject line
                html: `${req.body.message}<br/><br/>${req.body.firstname} ${req.body.lastname} - <b>${req.body.email}</b>`, // html body
            });
        } catch (error: any) {
            console.log(error);
            return res.status(error.statusCode || 500).json({ error: error.message });
        }
    
        return res.status(200).json({ error: "" });
    }
    
    export default contact;
    

    【讨论】:

      【解决方案3】:

      您可能需要在 Gmail 帐户中输入“Allow Less Secure Apps”(一直在底部)。您可能还需要“Allow access to your Google account”。 您可能还需要“Allow access to your Google account”。

      【讨论】:

      • 这解决了我的问题。我不再需要使用 Google 帐户网络链接重新签名。
      【解决方案4】:

      还有另一个选项可以使用 SendGrid 进行电子邮件传递而不会失败。很多时候,Nodemailer 会导致邮件失败,这可能会经常发生。

      Nodemailer可以在链接中找到。

      【讨论】:

      • 我不认为它回答了这个问题。
      【解决方案5】:

      使用 createTransport 中的nodemailer-smtp-transport 模块解决。

      var smtpTransport = require('nodemailer-smtp-transport');
      
      var transport = nodemailer.createTransport(smtpTransport({
          service: 'gmail',
          auth: {
              user: '*******@gmail.com',
              pass: '*****password'
          }
      }));
      

      【讨论】:

      • 如果我的密码中有@这样的特殊字符,我应该将它们转换成%40吗?
      【解决方案6】:

      工作正常:

      1- 安装nodemailer,如果没有安装则打包 (输入cmd):npm install nodemailer

      2- 转到https://myaccount.google.com/lesssecureapps 并打开允许安全性较低的应用程序

      3- 编写代码:

      var nodemailer = require('nodemailer');
      
      var transporter = nodemailer.createTransport({
          service: 'gmail',
          auth: {
              user: 'trueUsername@gmail.com',
              pass: 'truePassword'
          }
      });
      
      const mailOptions = {
          from: 'any@any.com', // sender address
          to: 'true@true.com', // list of receivers
          subject: 'test mail', // Subject line
          html: '<h1>this is a test mail.</h1>'// plain text body
      };
      
      transporter.sendMail(mailOptions, function (err, info) {
          if(err)
              console.log(err)
          else
              console.log(info);
      })
      

      4- 享受吧!

      【讨论】:

      • 谢谢!这真的很有帮助。
      【解决方案7】:

      先安装nodemailer

      npm install nodemailer  --save
      

      导入到js文件中

      const nodemailer = require("nodemailer");
      
      const smtpTransport = nodemailer.createTransport({
          service: "Gmail",
          auth: {
              user: "example@gmail.com",
              pass: "password"
          },
          tls: {
              rejectUnauthorized: false
          }
      });
      
      
      
      
      
      
       const mailOptions = {
              from: "example@gmail.com",
              to: sending@gmail.com,
              subject: "Welcome to ",
              text: 'hai send from me'.
          };
      
      
          smtpTransport.sendMail(mailOptions, function (error, response) {
              if (error) {
                  console.log(error);
              }
              else {
                  console.log("mail sent");
              }
          });
      

      在我的应用程序中工作

      【讨论】:

        【解决方案8】:

        出于某种原因,即使是验证码,仅允许不太安全的应用配置对我也不起作用。我必须执行另一个步骤,即启用 IMAP 配置:

        来自谷歌的帮助页面:https://support.google.com/mail/answer/7126229?p=WebLoginRequired&visit_id=1-636691283281086184-1917832285&rd=3#cantsignin

        • 点击右上角的设置设置。
        • 点击设置。
        • 单击“转发和 POP/IMAP”选项卡。
        • 在“IMAP 访问”部分中,选择 启用 IMAP。
        • 点击保存更改。

        【讨论】:

          【解决方案9】:

          我发现在Greg T's answer 中提到的this article 中描述的最简单的方法是创建一个应用密码,该密码在为帐户开启 2FA 后可用。

          myaccount.google.com > 登录和安全 > 登录 Google > 应用密码

          这将为您提供帐户的备用密码,然后您只需将 nodemailer 配置为普通 SMTP 服务。

          var smtpTransport = nodemailer.createTransport({
              host: "smtp.gmail.com",
              port: 587,
              auth: {
                  user: "username@gmail.com",
                  pass: "app password"
              }
          });
          

          虽然 Google 推荐 Oauth2 作为最佳选择,但此方法很简单,尚未在此问题中提及。

          额外提示:我还发现您可以将您的应用名称添加到“发件人”地址,GMail 不会像您尝试使用其他地址时那样仅将其替换为帐户电子邮件。 IE。

          from: 'My Pro App Name <username@gmail.com>'
          

          【讨论】:

          • 一直用这个1。您需要设置 2-factory auth 来设置应用密码。相反的安全性较低。
          【解决方案10】:

          只需添加“主机”就可以了。

          host: 'smtp.gmail.com'
          

          然后通过点击下面的链接启用“lesssecureapps”

          https://myaccount.google.com/lesssecureapps

          【讨论】:

            【解决方案11】:

            只要参加那些: 1-在您重新启动客户端浏览器之前,不接受允许低级别电子邮件的 Gmail 身份验证 2-如果您想使用 nodemailer 发送电子邮件并且您不想使用 xouath2 协议,您应该写为 secureconnection:false 如下所示

            const routes = require('express').Router();
            var nodemailer = require('nodemailer');
            var smtpTransport = require('nodemailer-smtp-transport');
            
            
            
            routes.get('/test', (req, res) => {
              res.status(200).json({ message: 'test!' });
            });
            
            routes.post('/Email', (req, res) =>{
            
                var smtpTransport = nodemailer.createTransport({
                    host: "smtp.gmail.com",
                    secureConnection: false,
                    port: 587,
                    requiresAuth: true,
                    domains: ["gmail.com", "googlemail.com"],
                    auth: {
                        user: "your gmail account", 
                        pass: "your password*"
                    }
            });  
            
              var mailOptions = {
                  from: 'from@gmail.com',
                  to:'to@gmail.com',
                  subject: req.body.subject,
                  //text: req.body.content,
                  html: '<p>'+req.body.content+' </p>'
              };
            
              smtpTransport.sendMail(mailOptions, (error, info) => {
                if (error) {
                    return console.log('Error while sending mail: ' + error);
                } else {
                    console.log('Message sent: %s', info.messageId);
                }
                smtpTransport.close();
            });  
            
            })
            
            module.exports = routes;
            

            【讨论】:

            • smtpTransport 用了两次,哪一次是什么?
            • 真的很清楚第一个是用于创建 smtpTransport 设置,第二个是使用此设置发送邮件,现在它在 firebase 中完美运行
            • 为什么你在 smtpTransport 中使用了两次 var?
            • 我不记得太多时间了,但你可以看到这是不同的范围。箭头功能使另一个范围这是非常基本的技术信息
            【解决方案12】:

            以上解决方案都不适合我。我使用了documentation of NodeMailer 中存在的代码。它看起来像这样:

            let transporter = nodemailer.createTransport({
                host: 'smtp.gmail.com',
                port: 465,
                secure: true,
                auth: {
                    type: 'OAuth2',
                    user: 'user@example.com',
                    serviceClient: '113600000000000000000',
                    privateKey: '-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...',
                    accessToken: 'ya29.Xx_XX0xxxxx-xX0X0XxXXxXxXXXxX0x',
                    expires: 1484314697598
                }
            }); 
            

            【讨论】:

            • 感谢好友! :) thissss ---> 主机:'smtp.gmail.com',端口:465,安全:true,为我工作
            • @PraveenVishnu 没问题,如果你投票赞成这个答案,更多的人会看到它。这也可能对他们有所帮助。
            • 您好,我知道这已经是旧的了,但是您介意您从哪里获得 serviceClient、privateKey 和 accessToken 吗?谢谢。
            • @AljohnYamaro 邮件服务会提供。就我而言,它是 Gmail。你可以在这里阅读更多:stackoverflow.com/questions/36214968/…
            【解决方案13】:

            简单的解决方案:

            var nodemailer = require('nodemailer');
            var smtpTransport = require('nodemailer-smtp-transport');
            
            var transporter = nodemailer.createTransport(smtpTransport({
              service: 'gmail',
              host: 'smtp.gmail.com',
              auth: {
                user: 'somerealemail@gmail.com',
                pass: 'realpasswordforaboveaccount'
              }
            }));
            
            var mailOptions = {
              from: 'somerealemail@gmail.com',
              to: 'friendsgmailacc@gmail.com',
              subject: 'Sending Email using Node.js[nodemailer]',
              text: 'That was easy!'
            };
            
            transporter.sendMail(mailOptions, function(error, info){
              if (error) {
                console.log(error);
              } else {
                console.log('Email sent: ' + info.response);
              }
            });  
            

            第 1 步:

            去这里https://myaccount.google.com/lesssecureapps 并启用不太安全的应用程序。如果这不起作用,那么

            第 2 步

            到这里https://accounts.google.com/DisplayUnlockCaptcha 并启用/继续,然后尝试。

            对我来说,仅第 1 步不起作用,所以我必须进行第 2 步。

            我还尝试删除 nodemailer-smtp-transport 包,令我惊讶的是它可以工作。但是当我重新启动系统时,它给了我同样的错误,所以我不得不去打开不太安全的应用程序(我在工作后禁用了它)。

            然后为了好玩,我只是尝试关闭(不太安全的应用程序)并且它再次工作!

            【讨论】:

            • 第 1 步和第 2 步非常有帮助。谢谢!在看到您的解决方案之前我尝试了第 1 步,但没有成功,但第 2 步很神奇!
            • "smptTransport 不是函数"
            • 我尝试了您与我们分享的两种方式,但我一次又一次地遇到相同的错误{错误:在 TCPConnectWrap.afterConnect [as oncomplete] 处连接 ETIMEDOUT 74.125.68.108:465 (net.js :1097:14) errno:'ETIMEDOUT',代码:'ECONNECTION',系统调用:'connect',地址:'74.125.68.108',端口:465,命令:'CONN'}
            • 必须先从我的默认 Gmail 中注销。由于某种原因,Gmail 不允许您更改默认帐户,也不允许您对所选帐户执行第二步。
            • 2020 更新:Nodemailer 不再需要 nodemailer-smtp-transport 包;它是内置的。您现在可以使用上面的代码和一个对象作为createTransport 的参数,而不是smtpTransport({}) 作为arg
            【解决方案14】:

            你所有的代码都没问题,剩下的就是去链接https://myaccount.google.com/security

            并继续向下滚动,您会发现允许不太安全的应用程序:打开并保持打开,您不会发现任何错误。

            【讨论】:

              【解决方案15】:
              exports.mailSend = (res, fileName, object1, object2, to, subject,   callback)=> {
              var smtpTransport = nodemailer.createTransport('SMTP',{ //smtpTransport
              host: 'hostname,
              port: 1234,
              secureConnection: false,
              //   tls: {
              //     ciphers:'SSLv3'
              // },
              auth: {
                user: 'username',
                pass: 'password'
              }
              
              });
              res.render(fileName, {
              info1: object1,
              info2: object2
              }, function (err, HTML) {
              
              smtpTransport.sendMail({
                from: "mail@from.com",
                to: to,
                subject: subject,
                html: HTML
              }
                , function (err, responseStatus) {
                    if(responseStatus)
                  console.log("checking dta", responseStatus.message);
                  callback(err, responseStatus)
                });
              });
              }
              

              您必须在代码中添加安全连接类型。

              【讨论】:

                【解决方案16】:

                查看 nodemailer 的连接 Gmail 的官方指南:

                https://community.nodemailer.com/using-gmail/

                -

                这样做后对我有用:

                1. 启用安全性较低的应用程序 - https://www.google.com/settings/security/lesssecureapps
                2. 暂时禁用验证码,以便您可以连接新设备/服务器 - https://accounts.google.com/b/0/displayunlockcaptcha

                【讨论】:

                • 2 号解决了我的问题。我在谷歌账户设置的任何地方都找不到那个链接。谢谢!
                • 这里也一样。我之前做过#1,并在 localhost 上收到电子邮件,然后转移到生产环境中,但没有任何效果。 #2 解决了我的生产问题。谢谢
                【解决方案17】:

                同样的问题也发生在我身上。我在 localhost 上测试了我的系统,然后部署到服务器(位于不同的国家/地区),然后当我在生产服务器上尝试系统时,我看到了这个错误。我尝试了这些来修复它:

                1. https://www.google.com/settings/security/lesssecureapps 已启用但不是我的解决方案
                2. https://g.co/allowaccess我在有限的时间内允许从外部访问,这解决了我的问题。

                【讨论】:

                • g.co/allowaccess 链接为我修复了它(已经启用了 lesssecureapps)-谢谢!
                【解决方案18】:

                对我来说,使用端口和安全性以这种方式工作(我在没有安全设置的情况下使用 PHP 从 gmail 发送电子邮件时遇到问题)

                我希望能帮助别人。

                var sendEmail = function(somedata){
                  var smtpConfig = {
                    host: 'smtp.gmail.com',
                    port: 465,
                    secure: true, // use SSL, 
                                  // you can try with TLS, but port is then 587
                    auth: {
                      user: '***@gmail.com', // Your email id
                      pass: '****' // Your password
                    }
                  };
                
                  var transporter = nodemailer.createTransport(smtpConfig);
                  // replace hardcoded options with data passed (somedata)
                  var mailOptions = {
                    from: 'xxxx@gmail.com', // sender address
                    to: 'yyyy@gmail.com', // list of receivers
                    subject: 'Test email', // Subject line
                    text: 'this is some text', //, // plaintext body
                    html: '<b>Hello world ✔</b>' // You can choose to send an HTML body instead
                  }
                
                  transporter.sendMail(mailOptions, function(error, info){
                    if(error){
                      return false;
                    }else{
                      console.log('Message sent: ' + info.response);
                      return true;
                    };
                  });
                }
                
                exports.contact = function(req, res){
                   // call sendEmail function and do something with it
                   sendEmail(somedata);
                }
                

                所有配置都列出了here(包括示例)

                【讨论】:

                  【解决方案19】:

                  我遇到了同样的问题。 Allowing "less secure apps" 在我的 Google 安全设置中让它工作了!

                  【讨论】:

                    【解决方案20】:

                    如果您使用 Express,express-mailerwrapsnodemailer非常好,并且非常易于使用:

                    //# config/mailer.js    
                    module.exports = function(app) {
                      if (!app.mailer) {
                        var mailer = require('express-mailer');
                        console.log('[MAIL] Mailer using user ' + app.config.mail.auth.user);
                        return mailer.extend(app, {
                          from: app.config.mail.auth.user,
                          host: 'smtp.gmail.com',
                          secureConnection: true,
                          port: 465,
                          transportMethod: 'SMTP',
                          auth: {
                            user: app.config.mail.auth.user,
                            pass: app.config.mail.auth.pass
                          }
                        });
                      }
                    };
                    
                    //# some.js
                    require('./config/mailer.js)(app);
                    app.mailer.send("path/to/express/views/some_view", {
                      to: ctx.email,
                      subject: ctx.subject,
                      context: ctx
                    }, function(err) {
                      if (err) {
                        console.error("[MAIL] Email failed", err);
                        return;
                      }
                      console.log("[MAIL] Email sent");
                    });
                    
                    //#some_view.ejs
                    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                    <html xmlns="http://www.w3.org/1999/xhtml">
                      <head>
                        <title><%= subject %></title>
                      </head>
                      <body>
                      ... 
                      </body>
                    </html>
                    

                    【讨论】:

                      【解决方案21】:

                      我通过访问以下网址解决了这个问题(使用我要发送邮件的帐户连接到谷歌时):

                      https://www.google.com/settings/security/lesssecureapps

                      在那里我启用了不太安全的应用程序。

                      完成

                      【讨论】:

                      • 干得好!它正在工作,虽然我认为这不是最好的主意......我收到了我的第一封电子邮件..Thx
                      • 如果不启用它,它甚至无法在本地环境中工作。他清楚地提到它在本地环境中工作,而不是在远程服务器上工作。解决方案是什么?
                      • 如果您的 gmail 帐户中有 2FA 身份验证,这对您没有帮助
                      • 这不是生产的正确解决方案
                      【解决方案22】:

                      尝试在您的 gmail 帐户中禁用验证码;可能是根据请求者的 IP 地址触发的。 见:How to use GMail as a free SMTP server and overcome captcha

                      【讨论】:

                        【解决方案23】:

                        我使用的是旧版本的 nodemailer 0.4.1 并且遇到了这个问题。我更新到 0.5.15,现在一切正常。

                        编辑 package.json 以反映更改

                        npm install
                        

                        【讨论】:

                        【解决方案24】:

                        您应该使用 XOAuth2 token 连接到 Gmail。不用担心,Nodemailer 已经知道了:

                        var smtpTransport = nodemailer.createTransport('SMTP', {
                            service: 'Gmail',
                            auth: {
                              XOAuth2: {
                                user: smtpConfig.user,
                                clientId: smtpConfig.client_id,
                                clientSecret: smtpConfig.client_secret,
                                refreshToken: smtpConfig.refresh_token,
                                accessToken: smtpConfig.access_token,
                                timeout: smtpConfig.access_timeout - Date.now()
                              }
                            }
                          };
                        

                        您需要前往Google Cloud Console 注册您的应用。然后,您需要检索您希望使用的帐户的访问令牌。你可以使用passportjs

                        这是它在我的代码中的样子:

                        var passport = require('passport'),
                            GoogleStrategy = require('./google_oauth2'),
                            config = require('../config');
                        
                        passport.use('google-imap', new GoogleStrategy({
                          clientID: config('google.api.client_id'),
                          clientSecret: config('google.api.client_secret')
                        }, function (accessToken, refreshToken, profile, done) {
                          console.log(accessToken, refreshToken, profile);
                          done(null, {
                            access_token: accessToken,
                            refresh_token: refreshToken,
                            profile: profile
                          });
                        }));
                        
                        exports.mount = function (app) {
                          app.get('/add-imap/:address?', function (req, res, next) {
                            passport.authorize('google-imap', {
                                scope: [
                                  'https://mail.google.com/',
                                  'https://www.googleapis.com/auth/userinfo.email'
                                ],
                                callbackURL: config('web.vhost') + '/add-imap',
                                accessType: 'offline',
                                approvalPrompt: 'force',
                                loginHint: req.params.address
                              })(req, res, function () {
                                res.send(req.user);
                              });
                          });
                        };
                        

                        【讨论】:

                        • 在 NodeJS 中使用 GMail 帐户发送电子邮件是否有更简单的解决方案?
                        • 您能解释一下passport.authorize 的作用以及为什么需要范围、callbackurl 等,为什么不能只使用clientId 和secret?
                        • passport.authorizepassport.authenticate 类似,只是它不尝试更新当前会话。您需要传递 callbackURL,因为在 OAuth 握手之后,Google 需要知道将用户重定向到哪里才能完成握手。
                        • 这应该是您在生产中工作时的正确解决方案
                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2022-10-08
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多