简体   繁体   English

Base64电子邮件附件未上传

[英]Base64 email attachments are not uploading

I am using the following script http://stuporglue.org/recieve-e-mail-and-save-attachments-with-a-php-script/ to handle my emails that get sent to me, however it seems if a user sends an email from mail or outlook or any email client that sends base64 attachments they are not being saved in the data base, and the body text of the email is also skiped. 我正在使用以下脚本http://stuporglue.org/recieve-e-mail-and-save-attachments-with-a-php-script/来处理我发送给我的电子邮件,但似乎是用户从邮件或Outlook或任何发送base64附件的电子邮件客户端发送电子邮件,这些附件未保存在数据库中,并且电子邮件的正文也被删除。

I am wondering if anyone sees an error in the code, as I have looked and dont see anything that sticks out. 我想知道是否有人在代码中看到错误,因为我看起来并没有看到任何突出的东西。

a closer look shows the following Mail.app sends its base64 like this. 仔细看看下面的 Mail.app会像这样发送它的base64。

    --Apple-Mail=_9E76B10A-4086-43B8-B835-78F184FA43FC
Content-Disposition: inline;
    filename=CV-IT.pdf
Content-Type: application/pdf;
    name="CV-IT.pdf"
Content-Transfer-Encoding: base64

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
1NVM1hk3kE1G3rlPZKL2CeZ+Hdp

while Gmail sends it like this. 而Gmail则像这样发送它。

Content-Type: application/pdf; name="CV-IT.pdf"
Content-Disposition: attachment; filename="CV-IT.pdf"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_gx86pbon0

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
1NVM1hk3kE1G3rlPZKL2CeZ+Hdp

The gmail attachment saves while the mail.app does not. 当mail.app没有时,gmail附件会保存。

disclaimer the problematic script in question has more issues, which I will not address, and the answer below is meant as a quick fix for the problem at hand, while hoping to enlighten some readers who were not able to diagnose the problems themselves. 免责声明有问题的剧本有更多的问题,我不会解决,下面的答案是为了解决手头的问题,同时希望启发一些无法自己诊断问题的读者。 /disclaimer /免责声明

There are two main problems. 有两个主要问题。

Problem 1: split header lines 问题1:拆分标题行

Look at these headers: 看看这些标题:

Content-Disposition: inline;
    filename=CV-IT.pdf
Content-Type: application/pdf;
    name="CV-IT.pdf"

versus

Content-Type: application/pdf; name="CV-IT.pdf"
Content-Disposition: attachment; filename="CV-IT.pdf"

Now look at the part that processes these lines: 现在看看处理这些行的部分:

$info = split("\n",$parts[0]);
..
foreach($info as $line)
{
    if( preg_match("/Content-Type: (.*);/",$line,$matches) )
    {
        $type = $matches[1];
    }
    if( preg_match("/Content-Disposition: attachment; filename=\"(.*)\"/",
        $line,$matches) ) {
        $name = time() . "_" . $matches[1];
    }
    ..
}

This splits the header in lines, and then tries to match every line. 这会将标题分成行,然后尝试匹配每一行。 Now look at the two headers. 现在看看两个标题。 The second (working) one has 2 lines, which are perfectly matched. 第二个(工作)有2条线,完美匹配。

The first (not working) one has 4 (!) lines. 第一个(不工作)有4(!)行。 None of these 4 lines matches the patterns. 这4条线都不匹配模式。

There are countless ways of tackling this problem, and I'll take a quick&dirty oneliner. 有无数种方法可以解决这个问题,我会采取快速和肮脏的oneliner。 Add this line before $info = split("\\n",$parts[0]); $info = split("\\n",$parts[0]); 之前添加此行$info = split("\\n",$parts[0]);

$parts[0] = preg_replace("/\r?\n\s+/"," ",$parts[0]);

it will turn the split headers into oneliners again by looking for newlines followed by whitespace, and replacing them with just one space. 它会通过查找换行后跟空格,并用一个空格替换它们,将拆分头再次转换为oneliner。

Problem 2: wrong pattern 问题2:错误的模式

Assuming you applied the fix above, you have this pattern: 假设你应用了上面的修复,你有这种模式:

if( preg_match("/Content-Disposition: attachment; filename=\"(.*)\"/", ...

trying to match this line: 试图匹配这一行:

Content-Disposition: inline; filename=CV-IT.pdf

Two things go wrong here: 这里出了两件事:

problem 2a: disposition inline/attachment 问题2a:处理内联/附件

The pattern clearly looks for the word "attachment", while the line says "inline". 该模式清楚地查找“附件”一词,而该行则表示“内联”。 This is fixed by replacing attachment by (attachment|inline) , which indicates an alternative. 这是通过用(attachment|inline)替换attachment来修复的,这表示替代方案。 (note that this also captures the disposition type) (注意,这也捕获了处置类型)

problem 2b: filename double quotes 问题2b:文件名双引号

The pattern further looks for filename="(.*)" , while the line has a filename without the quotes. 该模式进一步查找filename="(.*)" ,而该行具有不带引号的文件名。

This is also no major issue, if you insert ? 如果插入,这也不是主要问题? after the " , to indicate that the " is optional, all will work. " ,以表明"是可选的,一切都会起作用。 To make it perfect, you must also ensure that the . 为了使它完美,你还必须确保. will not match the ending " if available, so replace filename="(.*)" with: 将不匹配结尾"如果可用,所以替换filename="(.*)" with:

filename="?([^"]+)"?

where [^"]+ stands for 'anything but " '. 其中[^"]+代表”除了"的任何东西。

So if you change these lines: 所以,如果你改变这些行:

if( preg_match("/Content-Disposition: attachment; filename=\"(.*)\"/",
    $line,$matches) ) {
    $name = time() . "_" . $matches[1];
}

into

if( preg_match('/Content-Disposition: (attachment|inline); filename="?([^"]*)"?/',
    $line,$matches) ) {
    $disposition = $matches[1];
    $name = time() . "_" . $matches[2];
}

it should work. 它应该工作。 (note that I changed the pattern to use single quotes, so that you need not escape the double quotes, making things legible) (请注意,我将模式更改为使用单引号,因此您无需转义双引号,使事情清晰可读)

To make this script fool proof, you should really read the appropriate RFCs, to see what more is to be expected in email headers. 为了使这个脚本变得简单,你应该真正阅读相应的RFC,看看在电子邮件标题中还有什么需要。 This script has a lot of assumptions buried in it. 这个脚本有很多假设。

The problem is that my script is not looking for inline content, only for attached content. 问题是我的脚本不是在寻找内联内容,只是为了附加内容。 With the way you have attached the file, it is inline, hence the 使用您附加文件的方式,它是内联的,因此

Content-Disposition: inline; 内容处理:内联; filename=CV-IT.pdf 文件名= CV-IT.pdf

If you attach it, you would instead see Content-Disposition: attachment; 如果你附上它,你会看到Content-Disposition:attachment; filename="CV-IT.pdf" 文件名= “CV-IT.pdf”

The Content-Disposition handling is around line 54-64 of the script on my site (linked in original question). Content-Disposition处理位于我网站脚本的第54-64行(原始问题链接)。

seems you used preg_match to get the boundary of the mail near line 166: 似乎你使用preg_match获取第166行附近邮件的边界:

if (preg_match("/boundary=(.*boundary)$/",$line,$matches)){
    $boundary = $matches[1];

You used the "/" character as delimiter of pattern of regular expression and you have the "/" in your boundary content at the same time. 您使用“/”字符作为正则表达式模式的分隔符,并且您的边界内容中同时包含“/”。

So this may be the reason why your code does not work. 所以这可能是您的代码不起作用的原因。

Try this: 试试这个:

if (preg_match("{boundary=(.*boundary)$}",$line,$matches)){
    $boundary = $matches[1];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM