从Angular表单获取正确的JSON格式

时间:2016-07-17 14:16:12

标签: json angular

这是我原始问题的更新版本。 我创建了一个反馈表(ff),其中包含文本输入和文件输入,与[(ngModel)] =" feedback.message"绑定。 &安培; " feedback.screenshot&#34 ;.

控制台给了我这个错误" JSON.parse:JSON数据的第1行第1列意外的数据结束" 来自ff-service或ff-form组件文件。

我的表格:

<form #f="ngForm" (ngSubmit)="onSubmit(f.value)" >

            <div class="modal-body">
                <p class="lead-text"><strong>Bel ons</strong> op 0488 020 010</p>
                <p><em>of</em></p>

                    <div class="form-group">
                        <label for="message">Verzend bericht</label>
                        <textarea class="form-control" required [(ngModel)]="feedback.message" name="message" #message="ngModel" placeholder="Beschrijf uw vraag, feedback of idee" rows="3" ></textarea>
                        <div [hidden]="message.valid || message.pristine" class="alert alert-danger">
                            Geef aub een beschrijving
                        </div>
                        <label for="screenshot">Schermafbeelding toevoegen</label>
                        <input type="file" [(ngModel)]="feedback.screenshot" name="screenshot" #screenshot="ngModel">
                    </div>

            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Annuleren</button>
                <button type="submit" class="btn btn-default" [disabled]="!f.form.valid" >Verzenden</button>
            </div>

        </form>

这是我的组件文件。

import { Component, OnInit }    from '@angular/core';
import { NgForm }               from '@angular/common';

import { Feedback }             from './feedback';
import { FormService }          from './feedback-form.service';

@Component({
    selector: 'feedback-form',
    templateUrl: 'app/feedback-form.component.html',
    providers: [FormService]
})

export class FeedbackFormComponent implements OnInit {
    response: string;
    value: string;

    constructor(private _formService : FormService){  }

    public feedback: Feedback; 

    ngOnInit(){
        //initialize form
        this.feedback = {
            message: '',
            screenshot: ''
        }
    }

    submitted = false;

    onSubmit(form: Feedback) { 
        this._formService.sendMail(form)
            .subscribe(
                response => this.response = response,
                error => console.log(error)
            )
        this.submitted = true;
    }


    //TODO remove when we are done 
    get diagnostic(){
        return JSON.stringify(this.feedback);
    }
}

//https://angular.io/docs/ts/latest/guide/forms.html

我的form.service.ts文件:

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

@Injectable()

export class FormService {
    constructor(private _http: Http) {  
       }
    private _mailUrl = 'http://app/form-mailer.php';

    sendMail(value: any): Observable<any> {
        const body = new URLSearchParams(value);
        body.set('message',value.message);
        body.set('screenshot',value.screenshot);


        let headers = new Headers();
        headers.append('Content-Type','application/x-www-form-urlencoded');
        headers.append('Accept','application/json');
        //headers.append('Access-Control-Allow-Origin','*');
        return this._http.post(this._mailUrl, body.toString(), { headers: headers })
            .map(res => {
                res.json();
                console.log();
            })
            .catch(this.handleError)
    }

    private handleError (error: any) {
        // In a real world app, we might use a remote logging infrastructure
        let errMsg = (error.message) ? error.message :
        error.status ? `${error.status} - ${error.statusText}` : 'Server error';
        console.error(errMsg); // log to console instead
        return Observable.throw(errMsg);
    }
}

服务器端php代码:

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

error_reporting(0);

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

$formMsg            = $_POST['message'];
$formScreenshot     = $_POST['screenshot'];

$msg = "Message:\n $formMsg\n Screenshot:\n $formScreenshot";
mail('info@bla.be','Feedback',$msg);
echo json_encode($formData); 
?>

感谢您的帮助! 佛瑞德

1 个答案:

答案 0 :(得分:0)

更新2

我将首先分解我在form.service.ts文件中看到的问题。

  1. 当您实际需要字符串时,将Javascript对象传递给URLSearchParams构造函数。我不确定为什么这不会导致TypeScript抛出错误。
  2. 您正在使用URLSearchParams对象。我想你最终使用这个对象试图使用JSONP?但是JSONP专门用于处理“GET”动词而不是“POST”动词。您发送JSONP请求的服务器也必须支持它。
  3. 在你的Headers区域,你将“Content-Type”设置为“application / x-www-form-urlencoded”,这很奇怪,因为在你的PHP代码中你实际上解码了正文的内容,好像它是一个JSON字符串对象。我认为这一切都可能有效的原因是因为“application / x-www-form-urlencoded”基本上是“POST”请求体内的QueryString。这也可能让您解决您的CORS问题。
  4. 您需要与“Content-Type”保持一致,现在您正在将身体中的QueryString结构发送到PHP服务器,在服务器上将主体解释为JSON,这是不匹配的。
  5. 我想再次清楚,我的PHP体验缺乏。你说这实际上是通过电子邮件向你发送参数,所以PHP可能会为你做一些魔术。我无法解释为什么它在响应中返回NULL但它显然能够解析数据并通过电子邮件发送给您。您可能希望从一些PHP人员那里寻找更多信息。

    <强>更新

    根据您的反馈,您的PHP代码似乎没有返回json。我不是PHP专家,但看起来你需要做this

    echo json_encode($value);//replaces: echo $value ->name;
    

    如果我理解发生了什么,只包括标题是不足以让PHP返回你的数据json格式。

    同时删除“console.log(res);”和括号。正如rinukkusu在评论中指出的那样,使用lambda括号表示法时必须小心。

    听起来您发布的服务器没有以JSON格式返回结果。根据服务器配置的具体要求json可能会给你你想要的结果,例如在你的代码中我会添加另一个标题来告诉服务器你希望json中的结果。如果这没有帮助,我也会将响应记录到控制台,这样你就可以看到你得到的结果。

    let headers = new Headers();
    headers.append('Content-Type','application/x-www-urlencoded');
    //headers.append('Access-Control-Allow-Origin','*');
    headers.append('Accept','application/json');//<-------
    return this._http.post(this._mailUrl, body.toString(), { headers: headers })
        .map(res => {
             console.log(res);//<------------
             res.json();
         })
        .catch(this.handleError)
    

    如果res对象为空,您可能希望通过浏览器调试器或fiddler2观察http流量,并查看通信实际发生的情况。

    由于您已将cors标头注释掉,我只想指出,如果您接受json并且您正在进行跨域请求,那么服务器将需要使用浏览器之前需要的响应中的特定标头进行回复它将允许数据可用。