【问题标题】:Email wont send Angular 4 & PHP电子邮件不会发送 Angular 4 和 PHP
【发布时间】:2017-12-15 00:31:29
【问题描述】:

我正在尝试从我页面上的联系表单发送电子邮件,我正在使用 PHP 脚本将其发送到我的电子邮件,我正在关注 this 教程,我使用了他的示例它确实有效......但我似乎无法让它在我的应用程序中工作,起初我遇到了一些麻烦 404 错误但我随后发布了我的网站并将其放在实时服务器上,现在我'正在获取成功代码

但我没有收到电子邮件,所以我去了http://mysite/assets/email.php,我看到了这个错误

get-in-touch.component.ts

import { Component, OnInit } from '@angular/core';
import { AppService, IMessage } from '../../services/email.service';

@Component({
  selector: 'app-get-in-touch',
  templateUrl: './get-in-touch.component.html',
  styleUrls: ['./get-in-touch.component.scss'],
  providers: [AppService]
})
export class GetInTouchComponent implements OnInit {
  message: IMessage = {};

  constructor(
    private appService: AppService
  ) { }

  ngOnInit() {
  }

  sendEmail(message: IMessage) {
    this.appService.sendEmail(message).subscribe(res => {
      console.log('AppComponent Success', res);
    }, error => {
      console.log('AppComponent Error', error);
    });
  }

}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule, Routes, ActivatedRoute, ParamMap } from '@angular/router';


import { AppComponent } from './app.component';
import { GetInTouchComponent } from './get-in-touch/get-in-touch.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { httpModule } from @angular/forms;

export const ROUTES: Routes = [
  { path: 'get-in-touch', component: GetInTouchComponent }
];

 @NgModule({
   declarations: [
    AppComponent,
    GetInTouchComponent
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot(ROUTES),
    FormsModule,
    HttpModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

email.service.ts

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Resolve } from '@angular/router';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

export interface IMessage {
  name?: string;
  email?: string;
  message?: string;
}

@Injectable()
export class AppService {
  private emailUrl = '../app/get-in-touch/email.php';

  constructor(private http: Http) {

  }

  sendEmail(message: IMessage): Observable<IMessage> | any {
    return this.http.post(this.emailUrl, message)
      .map(response => {
        console.log('Sending email was successfull', response);
        return response;
      })
      .catch(error => {
        console.log('Sending email got error', error);
        return Observable.throw(error);
      });
  }
}

email.php

<?php

header('Content-type: application/json');

$errors = '';

if(empty($errors)){
    $postdata = file_get_contents("php://input");
    $request = json_decode($postdata);

    $from_email = $request->email;
    $message = $request->message;
    $from_name = $request->name;

    $to_email = $from_email;

    $contact = "<p><strong>Name: </strong> $from_name</p><p><strong>Email:</strong> $from_email</p>";
    $content = "<p>$message</p>";

    $website = "Thirsty Studios";
    $email_subject = "Contact Form";

    $email_body = '<html><body>';
    $email_body .= '$contact $content';
    $email_body .= '</body></html>';

    $headers .= "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
    $headers .= "From: $from_email\n";
    $headers .= "Reply-To: $from_email";

    mail($to_email,$email_subject,$email_body,$headers);

    $response_array['status'] = 'success';
    $response_array['from'] = $from_email;
    echo json_encode($response_array);
    echo json_encode($from_email);
    header($response_array);
    return $from_email;
} else {
    $response_array['status'] = 'error';
    echo json_encode($response_array);
    header('Location: /error.html');
}
?>

我以前从未做过这样的事情(Angular + PHP),但我已经完成了教程中所说的一切,但我似乎无法让它工作,任何帮助将不胜感激,请让我知道您是否需要更多信息

【问题讨论】:

  • 您是否可以在浏览器中实际访问此 URL localhost:4200/app/get-in-touch/email.php,因为您遇到 404 错误。
  • 嘿,是的,我尝试访问该 URL,但它不起作用所以我所做的是将 email.php 移动到我的资产文件夹中,并且我能够访问它.. 但我仍然得到同样的错误我想知道它是否因为我在本地主机上而不起作用?
  • 显示表单的页面的完整 URL 是什么?
  • 它在本地运行所以 localhost:4200/get-in-touch
  • 即使在您修复了 email.php URL 之后,您是否仍然遇到完全相同的第一个错误?如果不能,请更新您的第一个错误图像。谢谢

标签: javascript php angular email typescript


【解决方案1】:

我不是 100% 相信我可以给您一个准确的答案,但我认为您遇到了一些总体问题/困惑/误解,理解它们可能有助于您朝着正确的方向前进。

首先,您现在应该忽略角度,只考虑 PHP(您尝试过这样做)。 Angular 基本上是一个红鲱鱼:如果您可以让您的 PHP 脚本在不使用 Angular 的情况下发送电子邮件,那么让 Angular 使用 PHP 端点发送电子邮件将很容易。诀窍是您的脚本当前通过带有 JSON 的 POST 正文接受其输入,因此如果您只是在浏览器中加载它,则不会发生任何事情。相反,您可以使用 curl 之类的东西直接测试此端点。如果您安装了 curl,您可以从命令行执行以下操作:

curl -d '{"email":"johndoe@example.com", "message": "Hi", "name": "Conor Mancone"}' 'http://example.com/email.php'

d 标志指定发布数据(以及 POST 请求的隐含标志)。如果您没有在本地安装 curl,您可以使用 online curl 或安装 postman。这些是您现在不妨开始学习的工具。

这将使您更有效地调试 PHP 端点。最重要的是,您将能够直接看到输出。下一步是将输出复制并粘贴到jsonlint 之类的内容中。看起来你的 PHP 端点没有正确返回 JSON,这会让你弄清楚那部分。不过最重要的是,您可以忽略角度并找出您不发送电子邮件的原因。关于这一点,让我们进入 PHP 并讨论代码中的一些一般问题,这些问题可能会也可能不会导致您的问题,但肯定对您的事业没有帮助:

$errors = '';

if(empty($errors)){
    // send email
} else {
    // return error
}

对于第一次查看您的代码的人来说,第一部分是相当明显的。您将$errors 设为空,然后您的所有电子邮件发送逻辑都包含在if (empty($errors)) 条件中。丢失$errors 变量。失去那个if-else。永远不要在你的应用程序中留下实际上不做任何事情的代码。它只是让您有更多机会无缘无故地引入错误。

另外,这是一个小问题,但您没有进行任何输入验证。如果发布到您的端点的 JSON 缺少某些数据,您的脚本将会崩溃。有人可能会将 HTML 放入邮件中,这可能是令人讨厌的,或者最坏的情况是危险的。

您的脚本末尾还有一堆错误:

echo json_encode($response_array);
echo json_encode($from_email);
header($response_array);
return $from_email;

您正在将$response_array 作为 JSON 输出到浏览器,然后您在字符串 ($from_email) 上运行 json_encode,这甚至不会形成有效的 JSON,并且它们两者的组合肯定不会是有效的 JSON。您应该只有一个echo json_encode,否则结果将不是有效的 JSON,并且您的 Angular 前端会出现解析错误。

接下来,您将 $response_array 传递给 php header 函数。这绝对不是为你做任何事情。 header 需要一个字符串,而不是数组,用于在 HTTP 响应中设置 HTTP 标头键/值对。我无法想象您想将 $response_array 中的任何数据设置为 HTTP 标头响应值,即使您确实想这样做,也无法通过传入 $response_array 本身来实现。所以,一定要杀了这条线。 PHP 无论如何都会默默地忽略它。

同样,没有理由退货。 HTTP 请求正在执行的文件的返回将完全没有影响。通常,您不应该在函数之外返回(这不是函数)。虽然我不相信这条线会导致任何错误,但它也没有做任何事情。如果它没有做任何事情,则将其删除。为了清楚起见,我说的是这条线:return $from_email;

这个脚本应该做的就是读取帖子数据,发送电子邮件,然后回显对json_encode 的单个调用。除此之外,您的前端应用程序将无法读取无效的 JSON。同样,使用curl(或其他类似工具)直接调用您的 PHP 脚本并更轻松地对其进行调试。这样您就可以看到它正在输出什么并验证它是否返回了正确的 JSON。

电子邮件

现在,主要问题是:缺少电子邮件发送。您肯定有一些格式错误的邮件标头。每个邮件标头都需要以\r\n 结尾。你开始很好,但你的最后两个标题行没有正确结束。这可能足以让您的电子邮件发送尝试失败。 PHP 内置的mail 函数不能很好地通知您错误,因此您实际上最好使用更强大的邮件程序。如果您在配置电子邮件时出错,这将为您提供更好的反馈。 PHP 中一个常见的就是这个人:

https://github.com/PHPMailer/PHPMailer

我会先修复您的电子邮件标题,看看是否适合您。否则,您可能必须尝试使用​​实际的邮件程序。原因是电子邮件发送不起作用的下一个最常见的原因是现代垃圾邮件缓解措施。 PHP mail 函数将直接从服务器本身发送一封电子邮件。许多现代电子邮件系统(尤其是 gmail)会自动拒绝此类电子邮件,除非您发送的域名在 DNS 级别正确配置。但是,您是从任意电子邮件地址发送的($from_email 变量的内容,来自用户)。如今,许多电子邮件提供商会自动拒绝此类电子邮件,而 PHP 将不知道发生了什么,也不会给您任何提示。

而是从您控制的固定地址发送。传递电子邮件中的$from_email,或将其设置为回复。您最好的选择是使用实际的电子邮件地址并使用 SMTP 进行身份验证。 Gmail 实际上可以正常工作。您应该能够找到一些示例,说明如何将上述 PHPMailer 与 gmail 一起使用,以直接从您的 gmail 地址发送。这将最大限度地减少您的电子邮件被视为垃圾邮件被拒绝的机会,并为您提供额外的反馈(如果它在您的已发送邮箱中,但未显示,则它被视为垃圾邮件被拒绝)。

现在发送电子邮件很棘手。可不是调用mail函数那么简单。

【讨论】:

    【解决方案2】:

    此时似乎请求甚至没有到达您的 PHP 脚本,因为请求返回 404。第一个错误很可能发生,因为节点服务器不会执行 .php 文件。您将需要使用 xammp (或您的首选替代方案)之类的东西在不同的端口上设置本地 Apache 服务器。或者以其他方式向实时网络服务器提出您的请求。

    似乎第二条和第三条错误消息可能来自您的电子邮件服务中的.catch 回调,请尝试使用以下内容:

    .catch((error: Error) => {
      console.log('Sending email got error', error.message);
      return Observable.throw(error.message);
    });
    

    有一些使用 PHP 的替代方法,例如 formspree 甚至是 Gmail API,我相信您会通过谷歌搜索找到其他方法。但这里是example using fromspree

    您还应该能够稍微简化您的 PHP 脚本,如下所示:

    <?php
    $errors = '';
    
    if( empty( $errors ) ) {
    
        $response_array = array();
    
        $from_email = $_POST['email'];
        $message    = $_POST['message'];
        $from_name  = $_POST['name'];
    
        $to_email = $from_email;
    
        $contact = "<p><strong>Name: </strong> $from_name</p><p><strong>Email:</strong> $from_email</p>";
        $content = "<p>$message</p>";
    
        $website = "Thirsty Studios";
        $email_subject = "Contact Form";
    
        $email_body = "<html><body>";
        $email_body .= "$contact $content";
        $email_body .= "</body></html>";
    
        $headers .= "MIME-Version: 1.0\r\n";
        $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
        $headers .= "From: $from_email\n";
        $headers .= "Reply-To: $from_email";
    
        mail( $to_email, $email_subject, $email_body, $headers );
    
        $response_array['status'] = 'success';
        $response_array['from'] = $from_email;
        echo json_encode( $response_array );
    
    } else {
    
        $response_array['status'] = 'error';
        echo json_encode($response_array);
    }
    ?>
    

    【讨论】:

    • 所以我发布了我的项目并将其放在实时开发服务器上,我收到了我的成功消息(请参阅更新的问题)但我实际上并没有收到电子邮件..
    • 好的,我认为您可以稍微简化您的邮件脚本,请参阅更新后的答案。
    • @A61NN5 你检查你的垃圾邮件文件夹了吗?当您浏览电子邮件脚本时也会收到电子邮件吗?首先进行测试,然后您应该了解该错误。同样从您的代码中,这需要在双引号内,否则它只会打印变量 ´$email_body .= '$contact $content';´
    • 嘿,谢谢,经过大量调试后,我决定使用 formspree,它更简单,而且可以正常工作,感谢您的建议!
    猜你喜欢
    • 2011-08-02
    • 2014-05-30
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多