ReactJS aws заблокирован из-за предполетной политики CORS

#reactjs #amazon-web-services #aws-lambda #axios #aws-api-gateway

#reactjs #amazon-веб-сервисы #aws-lambda #axios #aws-api-шлюз

Вопрос:

Я пытался создать простой API запроса post, чтобы мой интерфейс ReactJS мог создавать записи и заполнять их в таблице в DynamoDB. Я создал таблицу DynamoDB, предоставил лямбда-функции разрешение на выполнение запросов к этой таблице и шлюзу API для использования URL-адреса для выполнения запросов rest api. Изначально для запроса интеграции в API gateway не было установлено значение lambda proxy, но по совету службы поддержки aws я включил его.

Это код, который я использую в своей лямбда-функции (с api gateway (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;
};
  

Когда я пытаюсь получить доступ к post api со следующим телом в тестовой области в lambda:

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

Я получил 200 OK, и данные заполнены в таблице DynamoDB. Он также корректно работает в postman, 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», затем попробовал ‘*’ в элементе управления Разрешить происхождение для обоих лямбда node.js код и метод публикации reactjs. Я в полной растерянности от того, что я мог бы сделать, чтобы исправить это, и мог бы воспользоваться некоторой помощью. Я относительно новичок в создании собственных функций для обработки запросов 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;
  

Комментарии:

1. Попробуйте разрешить * для заголовков в функции lambda. Также не отправляйте заголовки cors с вашим запросом axios, это неверно и на самом деле может быть причиной проблемы!

2. Если ваша функция завершается с ошибкой, политика cors 500 будет установлена API gateway на что-то отличное от того, что вы установили в лямбда.

3. Приношу свои извинения, я не включил заголовки в свой запрос axios, когда изначально создавал функцию. Я добавил это перед публикацией в качестве попытки «радуйся, Мария». Он возвращает ту же ошибку с заголовком и без заголовка в вызове axios.

4. Используете ли вы API Gateway V1 (REST API) или API Gateway V2 (HTTP API)?

5. API Gateway V1 (REST API). Я отредактирую свой первоначальный пост, чтобы включить эту деталь. Спасибо, что указали на это!

Ответ №1:

В частности, для моей настройки проблема заключалась в конфигурации моего шлюза api и процессе в lambda. Я не обрабатывал запрос ПАРАМЕТРОВ, что вызывало сбой шлюза (ошибка 502). Чтобы исправить это, в api gateway я бы установил тип запроса на интеграцию OPTIONS methods на MOCK. Это приводит к тому, что шлюз api просто удаляет любой запрос OPTIONS, который он получает, и пропускает следующий запрос post.

Это определенно не лучшая практика и будет обновлено для более изящной обработки запроса ОПЦИЙ, но сейчас это работает.

Ответ №2:

В этой замечательной статье объясняется решение: Политика AWS CORS с React

Вы должны разобраться во всех деталях, я также прочитал это несколько раз, чтобы понять, как правильно настроить заголовки для каждого запроса.

Комментарии:

1. Ссылки на medium вообще не помогают… для просмотра статьи необходимо оплатить подписку.