从CORS策略阻止从源“ S3_host_url”访问“ API_Gateway_URL”的访存

时间:2020-06-17 14:29:24

标签: amazon-web-services aws-lambda cors amazon-dynamodb aws-api-gateway

我知道这个问题以前曾被问过,但是我找不到解决我问题的答案,因此,如果重复,请原谅我。

我创建了一个Lambda函数,该函数从DynamoDB表读取数据。我为此Lambda函数创建了API网关。 当我直接在浏览器中点击URL时,我得到了预期的结果。但是,当我在我的react应用程序中获取URL时,出现以下错误(我已将React应用程序托管在具有静态网站托管功能的S3存储桶中)

访问“ API_gateway_url”以进行获取 来源“ S3_static_website_endpoint”已被阻止 通过CORS策略:对预检请求的响应未通过访问控制检查:请求的资源上不存在“ Access-Control-Allow-Origin”标头。

在网上搜索时,我发现需要在Lambda中设置“ Access-Control-Allow-Origin”标头,并且已经完成,但是仍然遇到相同的问题。

PS:我将在尝试错误一整天后发布此问题,并查看不同的答案,因此,如果您知道答案,请帮助我!

Lambda函数:

console.log('function starts');

const AWS = require('aws-sdk');
const dynamoDB = new AWS.DynamoDB.DocumentClient();

exports.handler = (event, context, callback) => {

    function formatResponse(data, code) {
      return { 
        statusCode: code,
        headers: {
          'Access-Control-Allow-Origin': '*', 
          "Access-Control-Allow-Credentials" : true,
          "Access-Control-Allow-Headers":"X-Api-Key"
        },
        body: JSON.stringify(data)
      }
    }

    let param = {
        TableName: 'tableName',
        Limit: 100 //maximum result of 100 items
    };

    //Will scan your entire table in dynamoDB and return results.
    dynamoDB.scan(param, function(err,data){
        if(err){
            return formatResponse(data, 400);
        }else{
            return formatResponse(data, 200);
        }
    });
}

反应应用程序:

import React from 'react';

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isLoading: true,
            dataSource: {}
        };
    }
    async componentDidMount() {
        try {
            const response = await fetch('API_gateway_url');
            let responseJson = await response.json();
            this.setState(
                {
                    isLoading: false,
                    dataSource: responseJson
                },
                function () { }
            );
        } catch (error) {
            console.error(error);
        }
    }

    render() {
        let { dataSource } = this.state;
        if (this.state.isLoading) {
            return <div>Loading...</div>;
        } else {
            return (
                <div>
                    {dataSource.Items.map(item => (
                        <div key={item.PlayerId}>
                            <h1>{item.PlayerId}</h1>
                            <li>{item.PlayerName}</li>
                            <li>{item.PlayerPosition}</li>
                            <li>{item.PlayerNationality}</li>
                        </div>
                    ))}
                </div>
            );
        }
    }
}
export default App;

2 个答案:

答案 0 :(得分:0)

我怀疑您的Lambda没有针对OPTIONS请求运行(即“预检”)。您可以在API网关中配置CORS,这应该可以解决此问题。参见Enabling CORS for a REST API resource

答案 1 :(得分:0)

此问题已通过使用cors软件包解决。 可以在这里找到实现: https://epsagon.com/blog/aws-lambda-express-getting-started-guide/