#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 вообще не помогают… для просмотра статьи необходимо оплатить подписку.