【问题标题】:Angular4 http.post To JSON Or PHPAngular4 http.post 到 JSON 或 PHP
【发布时间】:2017-06-13 03:32:06
【问题描述】:

我正在使用什么:

使用 Node 和 NPM 的 Angular 4 快速入门种子。

目标:

将数据发布到 .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);
    }
}

person-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 来发布到的 cmets,我编写了一个很小的 ​​test.php 文件,我得到了一个“Unexpected token

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

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

【问题讨论】:

  • 为什么要发布到 json 文件?该错误意味着此文件不存在或无法由发布请求处理。无论如何,如果你的 json 文件不在 API 后面,这根本不应该工作。
  • 我不明白你的反对意见,请解释一下。另外,我还没有构建一个 php api,所以我使用 json 来测试没有服务器的功能。继《英雄之旅》教程之后,下一步是从 .json 文件中获取数据。我已经这样做了,所以我尝试将数据发布到它作为我的下一步。为什么它不起作用?
  • 您不能只发布到文件,您必须发布到正在等待发布请求的服务。构建您提到的 API 并发布到该 API。
  • 那么,我不能发布到文件的原因是因为它必须在服务器上?我认为 api 只是一种向用户隐藏功能的方法,但仍然使用方法发布到文件。但是,根据您刚才所说,它似乎必须在服务器上,因此对于 php api,我将发布到 php,然后 php 会将解码的 json 数据添加到文件中。这或多或少是正确的理解吗?
  • @slanden 好吧,我假设您在使用 api 时会发布将某些内容放入数据库并且没有“文件”的帖子。但这是真的,您不能发布到项目中的静态文件。没有可能。

标签: angular


【解决方案1】:

问题1)http.post到json:

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

问题 2) http.post 到 php:

  • JSON 中位置 0 处的意外令牌

在这种情况下,这个错误是由我的 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,而是返回了以“

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 输入意外结束”。所以,我通过改变 echo 语句来回显一个语法正确的 json 对象来消除这个错误。

新的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 中。

【讨论】:

    猜你喜欢
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2015-07-25
    • 2014-07-04
    • 2018-02-02
    • 2017-04-09
    • 2016-05-05
    • 2017-03-08
    相关资源
    最近更新 更多