首页 文章

mailto:link中的换行符

提问于
浏览
6

我想在博客文章下面创建一个“转发给朋友”链接,该帖子打开我的电子邮件客户端并准备好了消息 . 我可以让它用于单行消息,但我希望能够在消息体内打破行 . 我怎样才能做到这一点?

<?php
printf(
    '<a href="mailto:?subject=%s&body=%s">Forward this to a friend</a>',
    the_title_attribute('echo=0'),
    sprintf('The link: %s Have a great day! Stefaan', get_the_permalink())
);
?>

如何在上面有空行的新行上开始“祝你有美好的一天!”

链接:...祝你有个美好的一天!斯特凡

我的博客使用带有Genesis主题的WordPress,我将我的代码放入启用了PHP的 genesis_footer_entry 钩子中(参见screenshot - 电子邮件文本是荷兰语) .

8 回答

  • 3

    您无法在 body 中使用HTML标签 mailto

    根据RFC 2368,这是不可能的:

    特殊的hname“body”表示关联的hvalue是消息的主体 . “body”hname应该包含消息的第一个text / plain正文部分的内容 . mailto URL主要用于生成实际上是自动处理内容的短文本消息(例如邮件列表的“订阅”消息),而不是一般的MIME主体 .

    所以任何解决方案都取决于HTML标签是不可能的 . 我建议的解决方案是使用 \r\n 和PHP函数 rawurlencode

    所以这是代码

    <?php
    
         printf( 
        '<a class="simple-mail-link" href="mailto:x@y.com?subject=%s&body=%s"><div class="label"><div class="dashicons dashicons-admin-plugins"></div>Forward this to a friend</div></a>', 
        'My Subject',
        rawurlencode(sprintf( "Hi there, this might be interesting for you.\r\nThis is the link: %s.\r\nHave a great day!\r\nStefaan", get_the_permalink()))
        );
    
    ?>
    

    注意:我尝试使用带有http://example.com/test.php的变量替换get_the_permalink()代码

    引用:

    MailTo with HTML body

    What is the equivalent of JavaScript's encodeURIcomponent in PHP?

  • 0

    Explanation

    a mailto: 是电子邮件地址的URI方案,与所有其他URI一样,字符需要转换为可以通过Internet传输的格式 .

    采用原始代码的简化形式来说明以下几点

    printf(<href="mailto:?subject=%s&body=%s">Description</a>, the_title_attribute( 'echo=0' ) , sprintf("content link:%s more content", get_the_permalink())
    

    代码按以下顺序运行

    • get_the_permalink() 获取您网页的网址

    • sprintf() 替换 $content 中的 %s 与步骤1的结果

    • print_f() 然后替换
      i)第一个 %s ,即 subject=%s ,获取结果 the_title_attribute( 'echo=0' ) ,我假设是页面或您的网站的 Headers ,然后ii)第二个 %sbody=%s 与步骤2的结果形成一个完整的 a mailto 链接

    为了保留换行符,您应该在输出之前将 $content 字符串转换为URL编码形式 .

    在使用 rawurlencode() 函数完成的PHP中,它根据 RFC 3986 将字符串中的换行符 \r\n 转换为 %0D%0A .

    由于百分号 % 用于 sprint_f() 中的转换规范,因此在字符串被 sprint_f() 格式化后应将字符串传递给 rawurlencode() ,因此使用 rawurlencode(sprint_f($string, $arg))


    Solution
    我已经完整地整理了解决方案,您可以将其复制并粘贴到您的小部件中,以避免因错误实施而导致的误报 .

    格式1和格式2包含基本相同的代码,这两种格式可以向您说明如何插入换行符,或者通过 pressing enter 或者2)由 typing in \r\n 进行换行 .

    我已经将 $content 设为一个单独的字符串,以便于编辑和编写代码 .

    Format 1

    <?php
      //Start new line by pressing enter
      //IMPORTANT NOTE: do not remove the %s 
        $content="Hi there, this might be interesting for you
        This is the link: %s
        Have a great day!
        Stefaan
        ";
      //No need to amend the code below  
        printf( 
                '<a class="simple-mail-link" href="mailto:?subject=%s&body=%s">
                <div class="label">
                <div class="dashicons dashicons-admin-plugins"></div>
                Forward this to a friend</div></a>',the_title_attribute( 'echo=0' ),
                rawurlencode(sprintf( $content,get_the_permalink()))
                );
    ?>
    

    Format 2

    <?php
      //Start new line by adding \r\n
      //IMPORTANT NOTE: do not remove the %s 
        $content="Hi there, this might be interesting for you\r\nThis is the link: %s\r\nHave a great day!\r\nStefaan";
     //No need to amend the code below          
        printf( 
                '<a class="simple-mail-link" href="mailto:?subject=%s&body=%s">
                <div class="label">
                <div class="dashicons dashicons-admin-plugins"></div>
                Forward this to a friend</div></a>',the_title_attribute( 'echo=0' ),
                rawurlencode(sprintf( $content,get_the_permalink()))
                );              
    ?>
    

    Demo

    <a class="simple-mail-link" href="mailto:?subject=Page%20Title&amp;body=Hi%20there%2C%20this%20might%20be%20interesting%20for%20you%0D%0AThis%20is%20the%20link%3A%20http%3A%2F%2Fblahblahblah.com%0D%0AHave%20a%20great%20day%21%0D%0AStefaan"><div class="label"> <div class="dashicons dashicons-admin-plugins"></div>Forward this to a friend</div></a></body>
    
  • 0

    根据电子邮件规范,每个电子邮件行都需要在旧的 <CR><LF> 对中结束 - 因此您需要在 sprintf() 字符串中使用 \r\n .

    "This is the link: %s.\r\n Have a great day!\r\n Stefaan"

    如果 \r\n 没有得到源语言限制 . 鉴于:

    • \r 是ASCII 13 (hex 0D

    • \n 是ASCII 10 (hex 0A

    也许你可以使用 "&#13;&#10;"

  • -1

    sprintf() 调用中添加另一个 %s 参数,并将换行符号 %0A (两次)的URL编码版本传递给它:

    printf( 
            '<a class="simple-mail-link" href="mailto:?subject=%s&body=%s"><div class="label"><div class="dashicons dashicons-admin-plugins"></div>Forward this to a friend</div></a>', 
            'subject',
            sprintf( 'Hi there, this might be interesting for you. This is the link: %s. %sHave a great day! Stefaan', "link-here", "%0A%0A" )
        );
    

    编辑:此外,您还可以将 %0A 添加到字符串本身,但您必须记住通过在它之前添加额外的一个来转义 % char:

    printf( 
            '<a class="simple-mail-link" href="mailto:?subject=%s&body=%s"><div class="label"><div class="dashicons dashicons-admin-plugins"></div>Forward this to a friend</div></a>', 
            'subject',
            sprintf( 'Hi there, this might be interesting for you. This is the link: %s. %%0A%%0AHave a great day! Stefaan', "link-here" )
        );
    
  • 0

    使用urlencoded字符串表示CR / LF

    %0D%0A
    

    你想要休息的地方 .

    在例子中

    <a 
     class="simple-mail-link" 
     href="mailto:?subject=hello&body=Hello%0D%0A%0D%0AWorld!"
    >
    
  • 3

    我决定彻底解决这个问题并解决在这里所做的所有尝试 . 如果你想要quick answer,请查看当前接受的 .

    工作方案

    要使用 mailto: URL body 参数中的文本,percent-encode它 . 在PHP中,使用rawurlencode() . 主题也应该被编码 .

    $subj = "Whatever subject";
    $body = "Multi-\r\nline\r\nbody";
    printf(
        "mailto:?subject=%s&body=%s",
        rawurlencode($subj),
        rawurlencode($body)
    );
    
    mailto:?subject=Whatever%2Osubject&body=Multi-%0D%0Aline%0D%0Abody
    

    要将其用作 HTML link 的目标,请将HTML中具有特殊含义的字符替换为实体引用 - 在PHP中使用htmlspecialchars(),和Wordpress有一个发烧友(和filtrable)esc_html() .

    $subj = "Whatever subject";
    $body = "Multi-\r\nline\r\nbody";
    printf(
        '<a href="%s">mailto: URL with multi-line body</a>',
        htmlspecialchars(sprintf(
            "mailto:?subject=%s&body=%s",
            rawurlencode($subj),
            rawurlencode($body)
        ), ENT_QUOTES)
    );
    
    <a href="mailto:?subject=Whatever%2Osubject&amp;Multi-%0D%0Aline%0D%0Abody">mailto: URL with multi-line body</a>
    

    我相信到现在为止,您知道如何修改PHP代码以生成这样的链接 .

    调试问题

    你必须处理 several levels of technologies ,每个都有自己的转义方案:

    • PHP(例如 "\n" 是带换行符的字符串,不带反斜杠和字母n;如果你需要,你需要转义反斜杠 - "\\n"

    • (s)printf(例如要打印文字 % ,你必须写 %%

    • HTML(例如 & 启动实体引用;从字面上看,它应该被编码为实体引用 &amp;

    • 网址(例如,空格不是网址的有效部分,且必须percent-encoded%20

    手动操作太多了,如果没有检查 intermediate steps ,请确保它是正确的 . 如果你得到任何错误的中间步骤,它就会被打破 .

    • 您是否验证了PHP代码的保存方式与您编写的完全相同?

    • 你看过它产生的HTML了吗?

    • 您是否尝试通过右键单击浏览器中的链接并选择“复制电子邮件地址”来复制URL?

    安全的方法是 manually construct the product of last step ,只有一旦工作,继续并尝试以编程方式生成它 . 在这种情况下,这样的产品是一旦粘贴到浏览器的位置栏中的URL就打开了预先填充多行体的邮件编辑器 . 你可以 begin with a simple working example and make it more and more complex ,直到它满足你的需求 . 当手动构建太繁琐时,您可能选择了太复杂的产品 - 选择最简单的产品仍然可以按照您想要的方式工作,以后可以增加复杂性 .

    如果即使手动构建URL也会卡住,那你就不走运了 . 要么你必须阅读更多关于这个主题,寻求帮助,或放弃 . 如果不仅仅是您,则问题出在您的浏览器和电子邮件客户端之间 . 其中至少有一个有bug . 根据我使用mailto:URL的经验,这并不罕见 . 即使你让它为你工作,你的博客的访问者可能没有那么幸运他们的设置 .


    旁白:HTML规范出现的尝试

    我花了很多时间来看看HTML规范中关于我在其他答案和问题本身中提出的尝试中看到的问题 . 特别:

    • 属性值中未编码的&符号

    • 属性值中的换行符
      在属性值的HTML标记( <br> )中

    • 未编码的 <>

    句法层面

    HTML实现现在非常强大,甚至HTML规范也变得非常宽松,将编号&符号( & )编码为实体引用( &amp; ;在HTML5中称为character references),因此通常不会这样做 . (但HTML 4规范要求编码 . )

    在HTML文件中的实际字节级别,引用attribute values in HTML5可以自由包含几乎*任何字符,但用于引用它们的引号除外(必须用字符引用替换) .

    *有关详细信息,请参阅HTML5规范中的预处理输入流和不明确的&符号 .

    这就是为什么即使换行和未编码的 <br> 在引用的属性值中也可以 . 但实际上,它们在 href 中不合适(与例如title不同),因为......

    语义级别

    在语义级别,当解析所有内容时,任何字符串(包括空字符串)都被允许作为属性值,但是specific attributes add further constraints .

    这就是HTML咬你的地方 - href指定包含valid URL potentially surrounded by spaces,不能包含

    • 中间的换行符和其他空格字符

    • <> ,以及许多其他角色 .

    这些字符必须是percent-encoded . 对于实际的definition of URL and its syntax,HTML规范遵循其他规范 .

    Handling invalid URLs is implementation-defined,这些机制在浏览器中可能不一致 . 只要尊重规格 . 我的Firefox忽略换行符并保留空格 - URL中也不允许使用空格,但Firefox在对URL执行任何其他操作之前对其进行编码 .

  • 2

    您可以在sprintf中添加 <br> 标记(假设您要为HTML显示分隔线):

    sprintf( 'Hi there, this might be interesting for you. This is the link: %s.<br> Have a great day!<br> Stefaan',get_the_permalink() )
    

    EDIT:

    如果您想要纯文本邮件,请使用 \r\n 和双引号:

    sprintf("Hi there, this might be interesting for you. This is the link: %s.\r\n Have a great day!\r\n Stefaan",get_the_permalink() )
    
  • -1

    你可能会在那里扔掉一个PHP_EOL

    <?php
         printf( 
            '<a class="simple-mail-link" href="mailto:?subject=%s&body=%s"><div class="label"><div class="dashicons dashicons-admin-plugins"></div>Forward this to a friend</div></a>', 
            the_title_attribute( 'echo=0' ),
            sprintf( 'Hi there, this might be interesting for you. This is the link: %s. %sHave a great day! %sStefaan',get_the_permalink(), PHP_EOL, PHP_EOL )
        );
    

相关问题