How to post traditional form into iframe within an

2020-08-02 07:39发布

问题:

I'm attempting to do a traditional form post into an iframe from within an Angular 4 app and it's simply posting into a new tab. I had trouble posting the form at all until I added ngNoForm to the form element so I'm assuming that I need to do something else (maybe to the iframe element?) My form tag looks like:

<form 
  ngNoForm
  method="POST"
  action="http://some.url"
  target="responseFrame"
  >

My iframe tag looks like:

<iframe id="responseFrame" name="responseFrame" src=""></iframe>

回答1:

Update: Take a look a look at this plunker. You will have to replace the demoEndpoint value with your desired endpoint in the component. The form action attribute in the template must also match your demoEndpoint. I tested this code with the only distinction of substituting my development endpoint with the demoEndpoint value and form action attribute value and it works correctly. https://plnkr.co/edit/NAJPfFyulzEQFtR01OML?p=info

// start: safe-resource-url.pipe.ts

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Pipe({ name: 'safeResourceUrl' })
export class SafeResourceUrlPipe implements PipeTransform {

  constructor(private domSanitizer: DomSanitizer) { }

  transform(url) {
    return this.domSanitizer.bypassSecurityTrustResourceUrl(url);
  }
}
// end: safe-resource-url.pipe.ts

// start: home.component.ts
import { Component, ViewChild, ElementRef, OnInit, AfterViewInit } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';

@Component({
  selector: 'home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit, AfterViewInit {
  @ViewChild('form') postForm: ElementRef;
  private a_field: any;
  private b_field: any;
  private c_field: any;
  private show_form: any;
  private demoEndpoint: any;
  private reqBody: any;

  constructor(private http: Http) {
    this.demoEndpoint = 'https://example.com/demoEndpoint'; /* this would be the url that you load with the iframe, that is also the value in the action field on the form to be issued in the post request */
    this.a_field = 'value a';
    this.b_field = 'value b';
    this.c_field = 'value c';
    this.show_form = 'PAYMENT_FORM';

    this.reqBody = new FormData();
    this.reqBody.append('a_field', this.a_field);
    this.reqBody.append('b_field', this.b_field);
    this.reqBody.append('c_field', this.c_field);
    this.reqBody.append('show_form', this.show_form);
  }

  ngOnInit() {
  /* too early to issue http post to the iFrame loaded from this.demoEndpoint */
  }

  ngAfterViewInit() {
    console.log('ngAfterViewInit trigger');
    this.postForm.nativeElement.submit();
  }

  submitForm($event): boolean {
    $event.stopPropagation();
    this.http.post(this.demoEndpoint, this.reqBody);
    console.log(this.reqBody);
    return true;
  }

  onLoad() {
    console.log('onLoad triggered.');
  }
}
// end: home.component.ts

// start: home.component.html
<iframe class="custom-frame" #frame width="400" height="400" id="frame" name="frame" frameborder="0" [src]="demoEndpoint | safeResourceUrl" (load)="onLoad()"></iframe>

<!-- The form is hidden on purpose and demonstrates automatically posting the form data to the endpoint loaded within the above iframe AfterViewInit. -->
<form target="frame" action="https://example.com/demoEndpoint" #form method="POST" (ngSubmit)="submitForm($event)">
    <input type="hidden" name="a_field" value={{a_field}} id="a_field" />
    <input type="hidden" name="b_field" value={{b_field}} id="b_field" />
    <input type="hidden" name="c_field" value={{c_field}} id="c_field" />
    <input type="hidden" name="show_form" value={{show_form}} />
</form>
// end: home.component.html