【问题标题】:AWS API Gateway Enable CORS allows OPTIONS but blocks POSTAWS API Gateway Enable CORS 允许 OPTIONS 但阻止 POST
【发布时间】:2018-07-16 09:10:33
【问题描述】:

我有一个 angular-5 组件,其形式如下:

    <form (ngSubmit)="onSubmit()" #contactForm="ngForm">
      <div class="form-group">
        <label for="name">Name</label>
        <input type="text" class="form-control" placeholder="Your first name" id="name" required
               [(ngModel)]="model.name" name="name" #name="ngModel"/>
        <div [hidden]="name.valid || name.pristine"
             class="alert alert-danger">
          Name is required
        </div>

        <label for="number">Number</label>
        <input type="text" class="form-control" placeholder="Your phone number" id="number"
               [(ngModel)]="model.number" name="number"/>

        <label for="email">Email</label>
        <input type="text" class="form-control" placeholder="Your email address" id="email" required
               [(ngModel)]="model.email" name="email" #email="ngModel"/>
        <div [hidden]="email.valid || email.pristine"
             class="alert alert-danger">
          Email is required
        </div>

        <label for="comment">Comment</label>
        <textarea type="text" class="form-control" placeholder="Your enquiry" id="comment" required
                  [(ngModel)]="model.comment" name="comment" #comment="ngModel"></textarea>
        <div [hidden]="comment.valid || comment.pristine"
             class="alert alert-danger">
          You need to say something
        </div>
      </div>
      <button type="submit" class="btn btn-success">Submit</button>
    </form>

它周围还有其他东西,但这是本质。

这由打字稿组件处理:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ContactPostService } from "../contact-post.service";
import {Contact} from "../contact";

@Component({
  selector: 'app-contact-form',
  templateUrl: './contact-form.component.html',
  styleUrls: ['./contact-form.component.css']
})
export class ContactFormComponent implements OnInit, OnDestroy {

  model: Contact = new Contact();

  submitted = false;

  constructor(private postService: ContactPostService) {}

  onSubmit() {

    console.log('from the form: ' + this.model.name + ', ' + this.model.number + ', ' + this.model.email + ', ' + this.model.comment);

    this.postService.saveContact(this.model)
      .subscribe(data => {
        console.log(data);
      });
    this.submitted = true;
  }

  ngOnInit() { }

  ngOnDestroy() { }

  newContact() {
    this.model = new Contact();
  }

}

然后是实际发布的服务:

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { Contact } from './contact';
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ContactPostService {

  private API_ENDPOINT = 'https://ovo5xmxf7e.execute-api.ap-southeast-2.amazonaws.com/prod/ContactFormLambda';

  constructor(private http: HttpClient) {}

  saveContact(form: any) {
    console.log('from the form: ' + form.name + ', ' + form.number + ', ' + form.email + ', ' + form.comment)

    let contact: Contact = {
      subject: 'Enquiry from ZenithWebFoundry',
      name: form.name,
      number: form.number,
      email: form.email,
      comment: form.comment
    };

    return this.http.post(this.API_ENDPOINT, contact)
      .pipe(
        catchError((error) => this.handleError(error))
      );
  }

  private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      console.error('An error occurred:', error.error.message);
    } else {
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    return new ErrorObservable(
      'Something bad happened; please try again later.');
  }
}

基本上,我在 AWS 中编写了将四个字段和一个主题值发布到 lambda。我已经从网关测试了 Lambda,我知道它可以工作(我收到了它发送的电子邮件。问题似乎是 Lambda 的 API 网关。一旦启用 CORS,我就会收到以下错误客户端控制台(Chrome 开发者工具)

发布 https://ovo5xmxf7e.execute-api.ap-southeast-2.amazonaws.com/prod/ContactFormLambda 500 () /contact:1 加载失败 https://ovo5xmxf7e.execute-api.ap-southeast-2.amazonaws.com/prod/ContactFormLambda: 请求中不存在“Access-Control-Allow-Origin”标头 资源。原点 'http://zenithwebfoundry.com' 因此不是 允许访问。响应的 HTTP 状态代码为 500。 main.630e523b47c705dd5494.bundle.js:1 后端返回代码 0,正文 是:[对象进度事件]

我发现 OPTIONS 工作正常:

请求

URL:https://ovo5xmxf7e.execute-api.ap-southeast-2.amazonaws.com/prod/ContactFormLambda
Request Method:OPTIONS
Status Code:200 
Remote Address:54.230.243.44:443
Referrer Policy:no-referrer-when-downgrade

响应标头

access-control-allow-headers:Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token
access-control-allow-methods:DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT
access-control-allow-origin:*
content-length:0
content-type:application/json
date:Tue, 06 Feb 2018 10:05:33 GMT
status:200
via:1.1 6884828476070d32978b45d03c1cc437.cloudfront.net (CloudFront)
x-amz-cf-id:DQ4SqBJgRRU9HG4jOLu03Jvg555B9Jv_J3KH9oczNWojhiIN14aCwA==
x-amzn-requestid:450ff8a0-0b25-11e8-850f-b3335987eeef
x-cache:Miss from cloudfront

注意它是如何返回“access-control-allow-origin:*”标头响应的,所以我原以为后面的 POST 是可以的,但是 POST 失败并出现上述错误

我从这个设置开始,只是为了允许任何来源:

并收到一条成功消息:

当我将“*”更改为域来源“http://zenithwebfoundry.com”时发生了同样的事情

那么如何使用 CORS 设置网关以使 POST 不被阻止?我做错了什么?

【问题讨论】:

    标签: amazon-web-services aws-lambda aws-api-gateway angular4-httpclient


    【解决方案1】:

    对于我的问题,我有一个部分答案,可以分享。基本上,当您在 API 网关中启用 CORS 时,它会添加标头

    access-control-allow-headers:Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token
    access-control-allow-methods:DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT
    access-control-allow-origin:*
    

    为您的选项响应。我遇到的问题是网关正在添加标头,但仅适用于 200 OK,如果 Lambda 以 500 响应,则标头未添加,并且 ajax 客户端会抛出错误。

    事实证明,当错误被抛出时,阻止电子邮件工作的真正问题是表单提交中存在阻止 lambda 工作、产生 500 并触发 ajax 错误条件的错误。我已经用工作代码更新了问题。

    现在,我似乎遇到了相反的问题,即使我为我的域启用了 CORS,电子邮件仍然是从非白名单域(在本例中为 localhost)发送的。当然,会引发 ajax 错误,但仍会发送电子邮件。在这种情况下,我会认为网关会阻止命令传递给 lambda。

    【讨论】:

      猜你喜欢
      • 2017-04-09
      • 2017-03-02
      • 1970-01-01
      • 2016-12-23
      • 2017-01-30
      • 2021-12-20
      • 2018-12-01
      • 2018-01-13
      • 2021-07-05
      相关资源
      最近更新 更多