У меня есть интерфейс React, который позволяет пользователям добавлять и просматривать рецепты, которые содержат текст и изображение.Бэкэнд представляет собой приложение Express Node.JS, которое выполняет чтение и запись в базу данных DynamoDB.Приложение развертывается на AWS с использованием Serverless Framework, поэтому оно использует API Gateway, Lambda, DynamoDB и S3 для хранения фотографий.Я работаю над тем, чтобы заставить работать маршрут загрузки фото, но ошибки CORS мешают ему работать.
Я импортировал модуль cors NPM и использую его в приложении.Я попытался подробно указать происхождение в конфигурации, но это не имеет значения.У меня также есть cors: true на каждом маршруте в моем файле serverless.yml.
serverless.yml excerpt:
service: recipes-api
provider:
name: aws
runtime: nodejs8.10
stage: dev
region: us-east-1
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource:
- { "Fn::GetAtt": ["RecipesDynamoDBTable", "Arn"] }
environment:
RECIPES_TABLE: ${self:custom.tableName}
S3_BUCKET: ${self:custom.bucketName}
functions:
app:
handler: index.handler
events:
- http: ANY /
- http: 'ANY {proxy+}'
getRecipe:
handler: index.handler
events:
- http:
path: recipes/{name}
method: get
cors: true
allRecipes:
handler: index.handler
events:
- http:
path: allrecipes
method: get
cors: true
addRecipe:
handler: index.handler
events:
- http:
path: recipes
method: post
cors: true
uploadPhoto:
handler: index.handler
events:
- http:
path: uploadphoto
method: post
cors: true
getPhoto:
handler: index.handler
events:
- http:
path: photo/{name}
method: get
cors: true
index.js excerpt:
const serverless = require('serverless-http');
const express = require('express');
const app = express();
const AWS = require('aws-sdk');
const cors = require('cors');
...
app.use(cors({origin: 'https://recipes.example.co'}))
//Upload Photo Endpoint
app.post('/uploadphoto', function (req, res) {
const s3 = new AWS.S3(); // Create a new instance of S3
const fileName = req.body.fileName;
const fileType = req.body.fileType;
const s3Params = {
Bucket: S3_BUCKET,
Key: fileName,
Expires: 500,
ContentType: fileType,
ACL: 'public-read'
};
s3.getSignedUrl('putObject', s3Params, (err, data) => {
if(err){
console.log(err);
res.json({success: false, error: err})
}
// Data payload of what we are sending back, the url of the signedRequest and a URL where we can access the content after its saved.
const returnData = {
signedRequest: data,
url: `https://${S3_BUCKET}.s3.amazonaws.com/${fileName}`
};
// Send it all back
res.json({success:true, data:{returnData}});
});
})
AddRecipeForm.js excerpt:
handleUpload = (ev) => {
console.log("handleUpload")
console.log(ev)
let file = this.uploadInput.files[0];
// Split the filename to get the name and type
let fileParts = this.uploadInput.files[0].name.split('.');
let fileName = fileParts[0];
let fileType = fileParts[1];
console.log("Preparing the upload");
axios.post("https://bqdu4plthq.execute-api.us-east-1.amazonaws.com/dev/uploadphoto",{
fileName : fileName,
fileType : fileType
})
.then(response => {
var returnData = response.data.data.returnData;
var signedRequest = returnData.signedRequest;
var url = returnData.url;
this.setState({url: url})
console.log("Recieved a signed request " + signedRequest);
// Put the fileType in the headers for the upload
var options = {
headers: {
'Content-Type': fileType
}
};
axios.put(signedRequest,file,options)
.then(result => {
console.log("Response from s3")
this.setState({success: true});
})
.catch(error => {
console.error(error);
})
})
.catch(error => {
console.error(error);
})
}
При нажатии кнопки «Загрузить фото», которая вызывает функцию handleUpload в AddRecipeForm.js, в моей консоли появляются следующие ошибки:
Origin https://recipes.example.co is not allowed by Access-Control-Allow-Origin.
XMLHttpRequest cannot load https://bqdu4plthq.execute-api.us-east-1.amazonaws.com/dev/uploadphoto due to access control checks.
Failed to load resource: Origin https://recipes.example.co is not allowed by Access-Control-Allow-Origin.
Обратите внимание, что работает любой другой маршрут (getRecipe, allRecipes, addRecipe) и отправляет заголовки CORS, поэтому я не уверен, почему мой запрос addphoto из React в API Gateway не отправляет заголовки CORS, даже если он должен использовать его в index.js.Заранее спасибо за помощь!