2016-07-17 37 views
0

这是我原来的问题的更新版本。 我创建了一个带有文本输入和文件输入的反馈表单(ff),绑定了[(ngModel)] =“feedback.message”&“feedback.screenshot”。从一个角度获取正确的JSON格式

控制台给我提供了这个错误“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('[email protected]','Feedback',$msg); 
echo json_encode($formData); 
?> 

感谢您的帮助! 弗雷德

回答

0

更新2

我要通过打破我在你的form.service.ts文件中看到的问题入手。

  1. 当它实际上需要一个字符串时,将一个JavaScript对象传入URLSearchParams构造函数。我不确定为什么这不会导致TypeScript引发错误。
  2. 您正在使用URLSearchParams对象。我想你最终使用这个对象来尝试使用JSONP?但是JSONP专门设计用于使用“GET”动词而不是“POST”动词。您发送JSONP请求的服务器也必须支持它。
  3. 在您的标题区域,您将“Content-Type”设置为“application/x-www-form-urlencoded”,这很奇怪,因为在您的PHP代码中,您实际上将身体内容解码为仿佛是JSON字符串对象。我认为这可能是一种工作的原因是因为“application/x-www-form-urlencoded”基本上是你的“POST”请求体内的一个QueryString。这也有可能让你解决你的CORS问题。
  4. 您需要与您的“Content-Type”保持一致,现在您正在将身体中的QueryString结构发送到PHP服务器,在您将该主体解释为JSON的服务器上,这是不匹配的。

我想再次清楚,我的PHP体验是缺乏的。你说这实际上是给你发送参数的邮件,所以PHP可能会为你做一些魔术。我无法解释为什么它在响应中返回NULL,但它显然能够解析数据并通过电子邮件发送给您。您可能希望从某些PHP人员那里获得更多信息。


UPDATE

根据大家的反馈,它看起来像你的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并且你正在做一个跨域请求,那么服务器需要在响应浏览器需要的特定头部响应回应然后才允许数据可用。

+0

小心,虽然为lambda表达式添加了括号,但你必须返回一些东西,因为它只隐含地返回没有括号 - >'return res.json();'(与问题无关,只是友好的提醒) – rinukkusu

+1

@ user3094909 - 更新了我的回答,以根据您的反馈提供进一步的指导。 –

+0

@丹西蒙 - 感谢您的输入。代码的巨大变化,我更新了。希望一切现在更清楚。 – Fred30