2017-12-15 106 views
5

Tôi đang cố gắng gửi email từ biểu mẫu liên hệ trên trang của tôi, tôi đang sử dụng tập lệnh PHP để gửi email tới email của mình, tôi đang theo dõi this hướng dẫn, tôi đã sử dụng ví dụ của mình và nó hoạt động ... nhưng tôi không thể làm cho nó hoạt động trong ứng dụng của mình, lúc đầu tôi gặp sự cố với lỗi 404 nhưng sau đó tôi xuất bản trang web của mình và đặt nó trên máy chủ trực tiếp và bây giờ tôi nhận được mã thành côngEmail không gửi Angular 4 & PHP

enter image description here

nhưng im không nhận được email, vì vậy tôi đã đi đến http://mysite/assets/email.php và Im nhìn thấy lỗi này

enter image description here

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'); 
} 
?> 

Tôi chưa bao giờ làm bất cứ điều gì như thế này trước (góc + PHP), nhưng tôi đã làm tất cả những gì được nói trong hướng dẫn và tôi dường như không thể có được nó để làm việc, bất kỳ trợ giúp nào sẽ được đánh giá cao và vui lòng cho tôi biết nếu bạn cần thêm thông tin

+0

Bạn có thể kiểm tra xem bạn có thực sự truy cập URL này http: // localhost: 4200/app/get-in-touch/email.php trong trình duyệt của mình hay không, vì bạn gặp lỗi 404. – ksoni

+0

Xin chào, tôi đã cố gắng truy cập URL đó và nó không hoạt động nên những gì tôi đã làm đã được chuyển email.php vào thư mục nội dung của tôi và tôi có thể truy cập vào nó .. nhưng tôi vẫn gặp lỗi tương tự tự hỏi nếu nó không hoạt động vì tôi đang trên localhost? – A61NN5

+0

URL đầy đủ của trang nơi biểu mẫu được hiển thị là gì? – ksoni

Trả lời

3

Tại thời điểm này có vẻ như yêu cầu thậm chí không đạt được tập lệnh PHP của bạn khi yêu cầu trả về 404. Lỗi đầu tiên có thể xảy ra vì máy chủ nút sẽ không thực thi các tệp .php. Bạn sẽ cần phải thiết lập máy chủ Apache cục bộ trên một cổng khác bằng cách sử dụng một cái gì đó như xammp (hoặc phương án thay thế ưa thích của bạn). Hoặc nếu không, yêu cầu của bạn đến một máy chủ web trực tiếp.

Nó có vẻ như các thông báo lỗi thứ hai và thứ ba có thể đến dưới hình thức .catch callback của bạn trong dịch vụ email của bạn, hãy thử sử dụng như sau:

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

Có một số lựa chọn thay thế để sử dụng PHP, như formspree hoặc thậm chí các Gmail API và tôi chắc chắn bạn sẽ tìm thấy những người khác với một chút Googling. Nhưng đây là example using fromspree.

Bạn cũng sẽ có thể đơn giản hóa bạn PHP kịch bản một chút như sau:

<?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); 
} 
?> 
+0

Vì vậy, tôi đã xuất bản dự án của mình và đặt nó trên máy chủ phát trực tiếp, Im nhận được thông báo thành công của tôi (xem câu hỏi được cập nhật) nhưng Im không thực sự nhận được email .. – A61NN5

+0

Ok, Tôi nghĩ bạn có thể đơn giản hóa kịch bản thư của bạn một chút, xem câu trả lời được cập nhật. – Und3rTow

+0

@ A61NN5 Bạn đã kiểm tra thư mục spam của mình chưa? Ngoài ra, bạn có nhận được email khi bạn duyệt qua tập lệnh email không? Kiểm tra đầu tiên và bạn nên hiểu lỗi sau đó. Ngoài ra từ mã của bạn điều này cần phải được bên trong báo giá gấp đôi, nếu không nó sẽ chỉ in biến '$ email_body.= '$ contact $ content'; ´ – Manzurul

3

Tôi không phải 100% tin rằng tôi có thể cung cấp cho bạn một câu trả lời chính xác, nhưng tôi nghĩ rằng có một số vấn đề chung/nhầm lẫn/hiểu lầm mà bạn đang gặp phải và hiểu chúng có thể giúp bạn di chuyển đúng hướng.

Trước hết, bạn nên bỏ qua góc hiện tại và chỉ xem xét PHP (mà bạn đã cố gắng thực hiện). Angular về cơ bản là một red-herring: nếu bạn có thể nhận được kịch bản PHP của bạn để gửi email mà không sử dụng Angular, sau đó nó sẽ được dễ dàng để có được Angular để gửi email bằng cách sử dụng điểm cuối PHP.Bí quyết là kịch bản của bạn hiện chấp nhận đầu vào của nó thông qua cơ thể POST với JSON, vì vậy nếu bạn chỉ đơn giản là tải nó lên trong trình duyệt của bạn, không có gì sẽ xảy ra. Thay vào đó bạn có thể kiểm tra điểm cuối này trực tiếp với những thứ như curl. Nếu bạn đã cài đặt curl bạn có thể làm một cái gì đó như thế này từ dòng lệnh:

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

Cờ d xác định dữ liệu sau (và ngầm cờ cho một yêu cầu POST). Nếu bạn không cài đặt curl cục bộ, bạn có thể sử dụng online curl hoặc cài đặt người đưa thư. Đây là những công cụ mà bạn có thể bắt đầu học ngay bây giờ.

Điều này sẽ cho phép bạn gỡ lỗi điểm cuối PHP của bạn hiệu quả hơn nhiều. Quan trọng nhất, bạn sẽ có thể xem kết quả trực tiếp. Bước tiếp theo là sao chép và dán đầu ra vào một cái gì đó như jsonlint. Có vẻ như điểm cuối PHP của bạn không trả lại đúng JSON, và điều này sẽ cho phép bạn tìm ra phần đó. Quan trọng nhất là, bạn có thể bỏ qua góc cạnh và tìm ra lý do tại sao bạn không gửi email. Ngày lưu ý rằng, chúng ta hãy nhảy vào PHP và nói về một số vấn đề chung trong mã của bạn, mà có thể hoặc không có thể gây ra vấn đề của mình, nhưng chắc chắn không giúp nguyên nhân của bạn:

$errors = ''; 

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

phần đầu tiên này khá rõ ràng đối với người xem mã của bạn lần đầu tiên. Bạn thực hiện $errors trống và sau đó tất cả logic gửi email của bạn được bao bọc trong điều kiện if (empty($errors)). Mất biến số $errors. Mất rằng nếu-else. Không bao giờ để lại mã trong ứng dụng của bạn mà không thực sự làm bất cứ điều gì. Nó chỉ cung cấp cho bạn nhiều cơ hội hơn để giới thiệu lỗi không có lý do.

Ngoài ra, đây là một điểm nhỏ, nhưng bạn không thực hiện bất kỳ xác thực nhập nào. Nếu JSON được đăng lên điểm cuối của bạn thiếu một số dữ liệu, tập lệnh của bạn sẽ bị lỗi. Ai đó có thể đặt HTML trong thông điệp có thể gây khó chịu tốt nhất hoặc nguy hiểm nhất.

Bạn cũng đã có một loạt các lỗi ở phần cuối của kịch bản của bạn:

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

Bạn đang outputting $response_array như JSON để trình duyệt, sau đó bạn đang chạy json_encode trên một chuỗi ($from_email) mà thắng thậm chí không tạo thành JSON hợp lệ và sự kết hợp cả hai đều chắc chắn sẽ không phải là JSON hợp lệ. Bạn chỉ nên có một echo json_encode, nếu không kết quả sẽ không phải là JSON hợp lệ và bạn sẽ nhận được lỗi phân tích cú pháp trong giao diện người dùng góc cạnh của mình.

Tiếp theo, bạn đang chuyển số $response_array của mình sang hàm php header. Điều này chắc chắn không làm bất cứ điều gì cho bạn. header đang mong đợi một chuỗi, không phải là mảng và được sử dụng để đặt cặp khóa/giá trị tiêu đề HTTP trong phản hồi HTTP. Tôi không thể tưởng tượng bạn muốn đặt bất kỳ dữ liệu nào trong các giá trị phản hồi tiêu đề HTTP của mình là $response_array và thậm chí nếu bạn muốn thực hiện điều đó, bạn không thể thực hiện điều đó bằng cách tự chuyển vào chính số $response_array. Vì vậy, chắc chắn giết chết dòng này. PHP là âm thầm bỏ qua nó anyway.

Tương tự, không có lý do gì để trả lại bất kỳ điều gì. Sự trở lại từ tệp đang được thực thi bởi yêu cầu HTTP sẽ không có tác động gì cả. Nói chung, bạn không nên quay trở lại bên ngoài các hàm (và đây không phải là một hàm). Trong khi tôi không tin rằng dòng này đang gây ra bất kỳ lỗi nào, nó cũng không làm bất cứ điều gì. Nếu nó không làm bất cứ điều gì sau đó loại bỏ nó. Để rõ ràng, tôi đang nói về dòng này: return $from_email;.

Tất cả tập lệnh này nên thực hiện là đọc trong dữ liệu bài đăng, gửi email và sau đó lặp lại một cuộc gọi đến json_encode.Bất cứ điều gì nhiều hơn thế sẽ kết thúc bằng JSON không hợp lệ mà ứng dụng front-end của bạn sẽ không thể đọc được. Một lần nữa, sử dụng curl (hoặc các công cụ tương tự khác) để gọi trực tiếp kịch bản PHP của bạn và gỡ lỗi nó dễ dàng hơn. Bằng cách này bạn có thể thấy nó xuất ra và xác minh rằng nó đang trả về JSON đúng.

Email

Bây giờ sau đó, vào vấn đề chính: thiếu email gửi. Bạn chắc chắn có một số tiêu đề thư không đúng định dạng. Mọi tiêu đề thư cần phải kết thúc bằng \r\n. Bạn bắt đầu tốt, nhưng hai dòng tiêu đề cuối cùng của bạn không kết thúc đúng cách. Điều này có thể đủ để chìm các nỗ lực gửi email của bạn. PHP được xây dựng trong mail chức năng không làm một công việc tuyệt vời của thông báo cho bạn về lỗi, vì vậy bạn thực sự có thể được tốt hơn bằng cách sử dụng một bưu phẩm mạnh mẽ hơn. Điều này sẽ cung cấp cho bạn phản hồi tốt hơn nếu bạn mắc lỗi trong khi định cấu hình email của mình. Một trong những phổ biến trong PHP là anh chàng này:

https://github.com/PHPMailer/PHPMailer

Tôi sẽ bắt đầu bằng cách sửa chữa tiêu đề email của bạn và xem nếu nào đó cho bạn. Nếu không, bạn có thể phải thử một bưu phẩm thực tế. Lý do là vì lý do phổ biến nhất tiếp theo vì sao gửi email không hoạt động là do những nỗ lực hiện đại của giảm thiểu spam. Chức năng PHP mail sẽ gửi một email trực tiếp từ chính máy chủ. Nhiều hệ thống email hiện đại (đặc biệt là gmail) sẽ tự động từ chối các email như vậy trừ khi tên miền bạn đang gửi được cấu hình đúng ở cấp DNS. Tuy nhiên, bạn đang gửi từ các địa chỉ email tùy ý (nội dung của biến số $from_email, xuất phát từ người dùng). Nhiều nhà cung cấp dịch vụ email trong những ngày này sẽ tự động từ chối các email như vậy và PHP sẽ không có ý tưởng nào xảy ra và sẽ không cung cấp cho bạn bất kỳ dấu hiệu nào về nó.

Thay vào đó, hãy gửi từ địa chỉ cố định mà bạn kiểm soát. Hoặc là vượt qua $from_email trong thông báo email hoặc đặt làm trả lời. Đặt cược tốt nhất của bạn là sử dụng địa chỉ email thực và xác thực bằng SMTP. Gmail thực sự hoạt động tốt cho việc này. Bạn sẽ có thể tìm thấy một số ví dụ về cách sử dụng PHPMailer ở trên với gmail để gửi trực tiếp từ địa chỉ gmail của bạn. Điều này sẽ giảm thiểu khả năng email của bạn bị từ chối là spam và cũng cung cấp cho bạn phản hồi bổ sung (nếu thư đó nằm trong hộp đã gửi của bạn, nhưng không hiển thị, thì thư bị từ chối là spam).

Gửi email rất khó khăn trong những ngày này. Nó không đơn giản như gọi hàm mail.

Các vấn đề liên quan