Значение Angular2 http.post для php сервера

Я пытаюсь отправить значения формы из проекта Ionic2 (наберите Angular2) на php-сервер, на котором я буду отправлять контактную почту.

Я не могу получить значения, которые я должен …

Вот мой form.service.ts:

import {Injectable}               from 'angular2/core';
import {Http, Response}           from 'angular2/http';
import {Headers, RequestOptions}  from 'angular2/http';
import {Observable}               from 'rxjs/Observable';

@Injectable()
export class FormService {
constructor (private _http: Http) {}

private _contactUrl = 'http://localhost:8888/Server/email.php';
// private _contactUrl = '/email';

sendMail(value: Object): Observable<any> {
const body = JSON.stringify(value);
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-urlencoded');
return this._http.post(this._contactUrl, body, {
headers : headers
}).map(res => res.json());
}
}

Который используется из моей функции onSubmit в моем form.ts:

import { Page, NavController } from 'ionic-angular';
import { Component } from 'angular2/core';
import { FORM_DIRECTIVES, FormBuilder,  ControlGroup, Validators, AbstractControl } from 'angular2/common';
import { Http, Response, Headers } from 'angular2/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
import { FormService} from './form.service';

@Page({
templateUrl: 'build/pages/form/form.html',
directives: [FORM_DIRECTIVES],
providers: [FormService]
})

export class Form {

contactForm: ControlGroup;
company: AbstractControl;
name: AbstractControl;
prenom: AbstractControl;
phone: AbstractControl;
email: AbstractControl;
website: AbstractControl;
message: AbstractControl;

arrivee: AbstractControl;
projet: AbstractControl;

projets = [
{ id: 1, label: 'Site Internet' },
{ id: 2, label: 'Site Intranet/Extranet' },
{ id: 3, label: 'Développement PHP' },
{ id: 4, label: 'Développement C#' },
{ id: 5, label: 'Conception Base de Données' },
{ id: 6, label: 'Tiers Maintenance Applicative' },
{ id: 7, label: "Recrutement d'un collaborateur Handicapé" }
];
arrivees = [
{ id: 1, label: 'Internet' },
{ id: 2, label: 'Recommandation' },
{ id: 3, label: 'Evênement' }
];

response: string;
value: any;

constructor(public nav: NavController, fb: FormBuilder, private _http: Http, private _formService: FormService) {
this.nav = nav;

// New controlGroup instance
this.contactForm = fb.group({
// Validators Rules for each field
// Champ XXX: ['', ...] correspondants au [ngFormControl]="XXX" de la vue HTML (inpput)
name: ['', Validators.compose([Validators.required, Validators.minLength(3), this.checkFirstCharacterValidator])],
prenom: ['', Validators.compose([Validators.minLength(3), this.checkFirstCharacterValidator])],
company: ['', Validators.compose([Validators.required, Validators.minLength(3), this.checkFirstCharacterValidator])],
projet: ['', Validators.required],
arrivee: ['', Validators.required],
phone: ['', Validators.compose([Validators.required, Validators.minLength(10)])],
email: ['', Validators.required],
website: ['', Validators.minLength(3)],
message: ['', Validators.compose([Validators.required, Validators.minLength(20)])]
});

this.name =     this.contactForm.controls['name'];
this.prenom =   this.contactForm.controls['prenom'];
this.company =  this.contactForm.controls['company'];
this.projet =   this.contactForm.controls['projet'];
this.arrivee =  this.contactForm.controls['arrivee'],
this.phone =    this.contactForm.controls['phone'],
this.email =    this.contactForm.controls['email'],
this.website =  this.contactForm.controls['website'],
this.message =  this.contactForm.controls['message']
}

// Check if firt character is a number
checkFirstCharacterValidator(control: Control): { [s: string]: boolean } {
if (control.value.match(/^\d/)) {
return { checkFirstCharacterValidator: true };
}
}

onSubmit(value) {
this._formService.sendMail({value})
.subscribe(
response => this.response = response,
error => console.log(error)
);
}
}

И в моем файле email.php я пытаюсь получить POST:

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

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers:        {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
exit(0);
}

$value = json_decode(file_get_contents('php://input'));

// for test
echo $value->name;

?>

Я проверил в консоли Chrome, я получаю что-то:
Скриншот из консоли

Как я могу получить сообщение от angular2 в мой php? Я что-то пропустил?

8

Решение

Я вижу две проблемы в вашем коде:

  • Вы создаете JSON-контент с помощью JSON.stringify, но для форм вам необходимо использовать URLSearchParams Класс или создать содержимое строки вручную.
  • Ваше значение типа контента неверно. Это application/x-www-form-urlencoded и не application/x-www-urlencoded,

Вот что вы должны использовать вместо этого:

sendMail(value: Object): Observable<any> {
const body = new URLSearchParams();
Object.keys(value).forEach(key => {
body.set(key, value[key]);
}

let headers = new Headers();
headers.append('Content-Type',
'application/x-www-form-urlencoded');
return this._http.post(this._contactUrl, body.toString(), {
headers : headers
}).map(res => res.json());
}
8

Другие решения

Мне удалось заставить это работать, это было только:

  sendMail(value: any): Observable<any> {
const body = new URLSearchParams(value);
body.set('name', value.name);
body.set('company', value.company);
body.set('projet', value.projet);
body.set('arrivee', value.arrivee);
body.set('phone', value.phone);
body.set('email', value.email);
body.set('website', value.website);
body.set('message', value.message);
body.set('name', value.name);

let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
return this._http.post(this._contactUrl, body.toString(), {
headers : headers
}).map(res => res.json());
}

И в форме .php:

<?php header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: X-Requested-With');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');

$formData = json_decode(file_get_contents('php://input'));
foreach ($formData as $key=>$value) {
$_POST[$key]=$value;
}

$formObject = $_POST['name'];
(...) ?>

Спасибо Тьерри Темплиеру за его драгоценную помощь.

4

Возможно для кого-то это будет полезно. У меня была проблема с вложенными объектами — при переходе к объектам PHP следующим образом:

var obj = {
value: 1,
innerObj: {
title: "title",
innerObject: {
value: 1
}
}
};

Я решил это с помощью парсер строки запроса

Пример использования:

//at top of you .ts file
let qs = require('qs');

return this.http.post(url, qs.stringify(data), {headers: this.postHeader})
.map((resp: Response) => resp.json())
.catch((error: any) => Observable.throw(error) || 'Server error');

Это также будет полезно для не вложенных объектов

1