Angular4 http.post到JSON或PHP

时间:2017-06-11 18:00:02

标签: angular

我使用的是什么:

使用Node和NPM的Angular 4 QuickStart种子。

目标:

将数据发布到.json文件。即将新人添加到people.json

中的数组

问题:

当我使用http.post方法将数据发布到.json文件时,我收到404错误,指出找不到file.json。

如果我使用http.get,它会很好地查找和检索数据。我传入的URL路径完全相同。

代码:

people.service.ts:

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';

import { Person} from './person';

@Injectable()
export class PeopleService
{
    private testUrl = './data/people.json';
    constructor(private http: Http) {}
    Create(param: any): Observable<Person> 
    {
        let headers = new Headers({ 'Content-Type': 'application/json' });
        let options = new RequestOptions({ headers: headers });

        return this.http.post(this.testUrl, body, options)
                        .map(this.extractData)
                        .catch(this.handleError);
    }

    /*
       HELPER/ERROR
    */
    private extractData(res: Response)
    {
        let body = res.json();
        return body.data || { };
    }

    private handleError (error: Response | any) 
    {
        let errMsg: string;
        if (error instanceof Response) 
        {
            const body = error.json() || '';
            const err = body.error || JSON.stringify(body);
            errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else 
        {
            errMsg = error.message ? error.message : error.toString();
        }
        console.error(errMsg);
        return Observable.throw(errMsg);
    }
}

人-detail.component.ts

import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/common';

import { Person} from './person';
import { PeopleService } from './people.service';

@Component({
    selector: 'person-detail',
    templateUrl: './person-detail.component.html',
    styleUrls: ['./person-detail.component.css']
})
export class PersonDetailComponent implements OnInit
{
    @Input() person: Person;
    errorMessage: string;

    ngOnInit(): void{}

    constructor(
        private peopleService: PeopleService,
        private route: ActivatedRoute,
        private location: Location
    ){}

    Add()
    {
        this.peopleService.Create(this.person).subscribe(/*person
=> person = this.person, error => this.errorMessage = <any>error*/);
    }
}

编辑:

根据需要服务器端API发布的评论,我写了一个很小的test.php文件,并且我得到了一个&#34;意外的令牌&lt;在JSON的位置0错误&#34;

阅读完这篇文章SyntaxError: Unexpected token < in JSON at position 0 at Object.parse (native) (AngularJS)之后,听起来我在json之前收到了html错误,导致JSON中出现意外令牌,但我不知道我可能会遇到什么错误得到我的php终端只说&#34; PHP注意:数组到C中的字符串转换:...&#34;

people.service.ts(仅限调整行)

import { Http, Response, Headers, RequestOptions } from '@angular/http';

private testUrl = 'http://localhost:8080/test.php';

Create(param: any): Observable<Person> 
{
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let urlParams = new URLSearchParams();
    urlParams.append('method', 'add');
    let options = new RequestOptions({ headers: headers, search: urlParams 
    });

    return this.http.post(this.testUrl, param, options)
                    .map(this.extractData)
                    .catch(this.handleError);
}

test.php的

<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-type");

$method = $_SERVER['REQUEST_METHOD'];
//$request = explode('/', trim($_SERVER['PATH_INFO'],'/'));
$input = json_decode(file_get_contents('php://input'),true);

echo "<br>";
echo "<br>";
echo "Request method: ".$method;
echo "<br>";
//echo "Request: ".$request;
echo "<br>";
echo "Request input: ".$input;

?>

PHP在PHP内置Web服务器上运行,该命令从项目文件夹中test.php的位置输入:

php -S localhost:8080 test.php

1 个答案:

答案 0 :(得分:0)

问题1)http.post到json:

  • 直接向json发布数据不可能。感谢R. Richards和AJT_82为我解决这个问题。

问题2)http.post到php:

  •   

    意外的令牌&lt;在位置0的JSON中

在这种情况下,此错误是由我的test.php文件引起的。没有返回适当的json。更改echo语句以回显json对象可以解决问题。

详细信息:

在我的PeopleService中,调用post()方法时没有错误,但以下map()方法是发生错误的地方。我传入一个自定义函数,其默认参数为Response对象extractData(res: Response)。此函数接受http请求的Response对象,该对象期待json:

people.service.ts

Create(param: any): Observable<Person> 
{
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });

    return this.http.post(this.testUrl, body, options)
                    .map(this.extractData)
                    .catch(this.handleError);
}

/*
   HELPER/ERROR
*/
private extractData(res: Response)
{
    let body = res.json();
    return body.data || { };
}

然而,在我的test.php文件中,我没有返回json,我正在返回以&#39;&lt;&#“开头的html标签(和php变量)的echo语句,因此是意外的令牌。 / p>

test.php的

<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-type");

$method = $_SERVER['REQUEST_METHOD'];
//$request = explode('/', trim($_SERVER['PATH_INFO'],'/'));
//$input = json_decode(file_get_contents('php://input'),true);

echo "<br>";  // this is where the unexpected token '<' comes from
echo "Request method: ".$method;   
?>

我无法删除echo语句,因为这会返回一个新的错误,指出JSON输入的意外结束&#34;。所以,我通过改变echo语句来回应一个语法正确的json对象来消除这个错误。

new test.php

<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-type");

$method = $_SERVER['REQUEST_METHOD'];
//$request = explode('/', trim($_SERVER['PATH_INFO'],'/'));
//$input = json_decode(file_get_contents('php://input'),true);
$myObj->data = "data";

echo json_encode($myObj);
?>

我还不明白为什么需要map()方法并从php返回一个json对象,但这就是我如何解决这个问题。

*请注意,php标头对于本地测试是临时的,并且出于安全原因不应该保留在生产php api中。