javascript React Native -发送包含获取但为空的PDF

pkwftd7m  于 2023-01-19  发布在  Java
关注(0)|答案(1)|浏览(109)

嘿,伙计们,我有一个关于从JavaScript和包Nodemailer获取函数的问题。

    • 注意:我正在使用Expo。**

我有一个PDF文件创建在我的模拟器看起来很好(充满了数据)。现在我想发送这个PDF文件到我的后端,在那里我想发送文件作为PDF文件,并得到它在我的邮件。
前端提取-调用我的后端:

async sendMonthReportMail(fileUri) {

    await fetch(`${connectionString}/api/mails/sendmonthreport`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        senderUser: "My Name",
        recieverMail: "myname@mymail.com",
        pathMonthLock: `${fileUri}`
      })
    })
    .then(res => res.json())
    .then(res => {
      console.log("Success SendMailMonthLock - " + res)
    })
    .catch(err => console.log("Error SendMailMonthLock - " + err))
  }

我也尝试过使用formData并将内容类型更改为"application/pdf",但这不起作用。
现在我的后端代码看起来像这样:

router.post("/sendmonthreport", async (req, res) => {
    const {recieverMail} = req.body;
    const {senderUser} = req.body;
    const {pathMonthLock} = req.body;

    let transport = nodemailer.createTransport({
      host: "mailserver",
      port: xx,
      secure: false,          
      tls: {    
        rejectUnauthorized: false     
      }
    });

    var message = {
      from: "My Sendermail <sender@mail.com>",
      to: `${recieverMail}`,
      subject: `Mail comming from - ${senderUser}`,
      text: `EmailText `,
      attachments:[{
        filename: "MyFilename.pdf",
        content: __dirname + `./${pathMonthLock}`,
      }] 
    }    

    await transport.sendMail(message)
    .catch(err => console.log("Error Mail: " + err ))

    res.send("email send")
  })

现在,我选择文件. uri的方式被用于Expo的DocumentPicker抛出。
我现在的问题是,邮件得到正确发送,并有一个PDF附加到它与正确的名称。然而,当我看PDF大小只有500字节,它是完全空的。当试图打开通过邮件发送的文件,然后它告诉我,该文件已损坏或格式错误。
如何发送PDF中的实际内容?
当我尝试使用formData时:

async sendMonthReportMail(file) {

    fdPost.append("file", file);
    fdPost.append("senderUser", "User Name");
    fdPost.append("recieverMail", "username@mail.com");

    console.log(fdPost);

    await fetch(`${connectionString}/api/mails/sendmonthreport`, {
      method: "POST",
      headers: {
        accept: "application/json"
        // "Content-Type": "multipart/form-data",
        // "Content-Type": "application/json",
        // "Content-Type" : "application/pdf"
        // "Content-Type": "application/x-www-form-urlencoded"
      },

      body: fdPost                                

    })
    .then(res => res.json())
    .then(res => {
      console.log("Success SendMailMonthLock - " + res)
    })
    .catch(err => console.log("Error SendMailMonthLock - " + err))
  }

fdPost是在我的文件console. logging的顶部定义的,它给了我一个有效的FormData,但是请求以网络错误结束!

Error SendMailMonthLock - TypeError: Network request failed

我的后端也不会对该调用作出React。
我也尝试过使用rn获取blob,但它只适用于react原生项目。我正在使用expo,所以这对我来说不是一个解决方案!
编辑:
我尝试了评论中的建议(使用Multer):
前端:

async sendMonthReportMail(file) {

    fdPost.append("file", file);
    fdPost.append("senderUser", "name");
    fdPost.append("recieverMail", "mail@mail.com");

    await fetch(`${connectionString}/api/mails/sendmonthreportTest`, {
      method: "POST",
      headers: {
        Accept: "application/json",
        'Content-Type': 'multipart/form-data'
        },
      body: fdPost                                 

    })
    .catch(err => console.log("Error SendMailMonthLock - " + err))
  }

后端:

router.post("/sendmonthreportTest", upload.single("file"), (req, res) => {                                                                  
  console.dir(req.file + req.body); 
})

我仍然有同样的问题!它给我类型错误:网络错误。
此外,当我试图调用这一点与 Postman ,我得到:

POST /api/mails/sendmonthreportTest 500 6.952 ms - 1221
TypeError: Cannot convert object to primitive value

要在提取前console.log fdPost时确认POST主体:

{"_parts":[["file",{"size":69496,"name":"Monatsbericht_User_Name_Dezember2022.pdf","type":"success","uri":"file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540yxxx%252Fxxx/DocumentPicker/2xx07e4-4136-4b6f-ad70-26xxac64064.pdf","mimeType":"application/pdf"}],["senderUser","User Name"],["recieverMail","user@mail.com"]]}
goqiplq2

goqiplq21#

看起来您正在尝试将PDF的文件URI而不是实际文件内容发送到后端。要发送文件的实际内容,您可以使用react-native-fs包读取文件并将其转换为base64。然后您可以在获取请求的正文中发送base64编码的文件。
可以使用以下代码读取该文件并将其转换为base64:

import RNFS from 'react-native-fs';

async sendMonthReportMail(fileUri) {
    let file = await RNFS.readFile(fileUri, 'base64');

    await fetch(`${connectionString}/api/mails/sendmonthreport`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        senderUser: "My Name",
        recieverMail: "myname@mymail.com",
        file: file
      })
    })
    .then(res => res.json())
    .then(res => {
      console.log("Success SendMailMonthLock - " + res)
    })
    .catch(err => console.log("Error SendMailMonthLock - " + err))
  }

在后端,您可以使用Buffer类将base64编码文件转换回二进制格式,然后将其附加到电子邮件中。

router.post("/sendmonthreport", async (req, res) => {
    const {recieverMail} = req.body;
    const {senderUser} = req.body;
    const {file} = req.body;

    let transport = nodemailer.createTransport({
      host: "mailserver",
      port: xx,
      secure: false,          
      tls: {    
        rejectUnauthorized: false     
      }
    });

    var message = {
      from: "My Sendermail <sender@mail.com>",
      to: `${recieverMail}`,
      subject: `Mail comming from - ${senderUser}`,
      text: `EmailText `,
      attachments:[{
        filename: "MyFilename.pdf",
        content: new Buffer(file, 'base64')
      }] 
    }    

    await transport.sendMail(message)
    .catch(err => console.log("Error Mail: " + err ))

    res.send("email send")
  })

此外,您必须检查文件大小限制和文件类型,因为一些电子邮件服务可能会拒绝大附件或某些文件类型。

相关问题