首页 > 解决方案 > ReactJS aws 被 CORS 预检策略阻止

问题描述

我一直在尝试制作一个简单的发布请求 api,以便我的 reactJS 前端可以发布帖子,并将它们填充到 DynamoDB 的表中。我创建了一个 dynamoDB 表,授予了 lambda 函数权限以向该表发出请求,以及一个 API 网关使用 url 发出其余的 api 请求。我最初没有将 API 网关中的集成请求设置为 lambda 代理,但根据 aws 支持的建议,我启用了它。

这是我在 lambda 函数中使用的代码(以 api 网关(REST API)作为触发器):

const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region: "us-east-1"});

exports.handler = (event, context, callback) => {
    console.log("Processing...");
    
    const {name} = JSON.parse(event.body);
    
    const params = {
        TableName: "serverlessAppTest",
        Item: {
            date: Date.now(),
            name: name,
        },
    };
    
    let responseBody = {
        name: name,
    }
    
    const response = {
    statusCode: 200,
    
    headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Credentials': true,
        "Access-Control-Allow-Headers" : "Content-Type",
        "Access-Control-Allow-Methods": "OPTIONS,POST,GET"
    },
    body: JSON.stringify(responseBody)
  };
    
    docClient.put(params, function(err, data) {
        if(err){
            callback(err, null);
        } else {
            callback(null, data);
        }
    })
    console.log("response: " +JSON.stringify(response))
    return response;
};

当我尝试在 lambda 的测试区域中使用以下主体到达 post api 时:

{
  "body": "{\"name\": \"Value from Lambda\"}"
}

我得到了 200 OK,数据填充到 dynamoDB 表中。它在邮递员中也可以正常工作,200 OK 并上传数据。

当我尝试使用我的 reactjs 代码时,我得到以下响应:

Access to XMLHttpRequest at 'https://{apivalhere}.execute-api.us-east-1.amazonaws.com/default/serverlessAPICalls' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

这是我的 reactjs 函数,可以通过按钮进行调用。

import React from "react";
import axios from "axios";

function FormHook() {
    const apiURL =
        "https://{apivalhere}.execute-api.us-east-1.amazonaws.com/default/serverlessAPICalls";

    const submitHandler = (e) => {
        e.preventDefault();
        console.log("did it");
        const headerData = {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Credentials": true,
            "Access-Control-Allow-Headers":
                "Origin, Content-Type, X-Auth-Token",
            "Access-Control-Allow-Methods":
                "GET, POST, PATCH, PUT, DELETE, OPTIONS",
        };
        axios
            .post(
                apiURL,
                {
                    name: "Hello from reactjs!",
                    message: "this is the message field.",
                },
                {
                    headers: headerData,
                }
            )
            .then((res) => {
                console.log(res);
                console.log(res.data);
            })
            .catch((err) => {
                console.log(err);
            });
    };

    return (
        <div>
            <form onSubmit={submitHandler}>
                <button type="submit">Send</button>
            </form>
        </div>
    );
}
export default FormHook;

我已经阅读了大约十几个关于 stackoverflow 和 aws 支持的文档,试图解决这个问题,但我一直被这个 cors 问题阻止。我已经尝试在我的标题中特别声明“application/json”,并特别允许“localhost:3000”,然后在 lambda node.js 代码和 reactjs post 方法的 Control Allow Origin 中尝试“*”。我完全不知道我能做些什么来解决这个问题,并且可以使用一些帮助。我在制作自己的函数来处理 api 请求方面相对较新,因此非常感谢任何指导或建议。

编辑:我也收到了与以下相同的 CORS 错误。

import React from "react";
import axios from "axios";

function FormHook() {
    const apiURL =
        "https://{apivalhere}.execute-api.us-east-1.amazonaws.com/default/serverlessAPICalls";

    const submitHandler = (e) => {
        e.preventDefault();
        console.log("did it");
        axios
            .post(
                apiURL,
                {
                    name: "Hello from reactjs!",
                    message: "this is the message field.",
                },
            )
            .then((res) => {
                console.log(res);
                console.log(res.data);
            })
            .catch((err) => {
                console.log(err);
            });
    };

    return (
        <div>
            <form onSubmit={submitHandler}>
                <button type="submit">Send</button>
            </form>
        </div>
    );
}
export default FormHook;

标签: reactjsamazon-web-servicesaws-lambdaaxiosaws-api-gateway

解决方案


特别是对于我的设置,问题出在我的 api 网关配置和 lambda 进程中。我没有处理导致网关错误(502 错误)的 OPTIONS 请求。为了解决这个问题,在 api 网关中,我将 OPTIONS 方法集成请求类型设置为 MOCK。这会导致 api 网关丢弃它获得的任何 OPTIONS 请求,并允许以下 post 请求通过。

这绝对不是最佳实践,将更新以更优雅地处理 OPTIONS 请求,但它现在正在工作。


推荐阅读