【问题标题】:Website javascript works locally, but not on AWS网站 javascript 在本地工作,但不在 AWS 上
【发布时间】:2021-02-18 16:09:25
【问题描述】:

我在 AWS 上托管一个静态网站(存储在 S3 中,CloudFront + Lambda@Edge)。我添加了一些基本的 javascript 来响应按钮点击(因为我将使用 AJAX 等将表单数据发送到 AWS API Gateway),但是 javascript 似乎只能在本地工作,而不是在线

具体来说,如果您转到my website 并单击按钮,则无论您在文本字段中输入什么内容,都不会发生任何事情。但是,如果您“查看页面源代码”并将其保存在本地,它将按预期响应(弹出警报和文本字段会根据 id 是否有效而改变颜色)。

我使用 jslint 和 regex101 来检查和清理我的代码。我已经删除了所有 CSS 和不相关的内容。我还在几个设备和浏览器上重现了这个问题(在本地总是可以正常工作)。我对 AWS 和 Javascript 还很陌生,所以也许这是一些基本的东西,但几天后我遇到了障碍。任何帮助将不胜感激!

我正在复制下面的 html(供后代使用):

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Why U No Work???</title>

    <script>
        function submitToAwsApiGateway(e) {
            e.preventDefault();

            // Validate id.
            // Length is 4-20 characters. Can have letters, numbers, spaces, and
            // some punctuation (!, @, #, &, *, (, ), -, _, +, =, [, ], |, :, .)
            // but not all ($, %, ^, {, }, ;, ", ', <, >, ?).
            const idRegex = /^[a-zA-Z0-9!@#&*()_+=|:.\u0020\-\[\]]{4,20}$/;
            var idValue = document.getElementById("id").value;
            if (!idRegex.test(idValue)) {
                document.getElementById("id").style.borderColor = "red";
                window.alert("Invalid id!");
                return;
            }
            document.getElementById("id").style.borderColor = "green";
            window.alert("Regex let this pass through.");
        }
    </script>
</head>

<body>
    <h1>Blah Blah</h1>
    <form id="getRecommendations" method="post">
        <input type="text" id="id" placeholder="Enter your id" maxlength="20" autofocus>
        <button type="button" onClick="submitToAwsApiGateway(event)">Do Something!</button>
    </form>
</body>
</html>

更新 感谢评论者将我指向浏览器中的开发人员工具 > 控制台。我得到以下输出:

Refused to execute inline script because it violates the following Content Security Policy directive: "default-src 'none'". Either the 'unsafe-inline' keyword, a hash ('sha256-jTQewrwZXhw320PnyfMo9c2+HHfh5l+pWVDLQMo/7rE='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.

所以我认为这一定与我的 Lambda@Edge 安全措施有关。即Content Security Policy。我看看能不能调试...

【问题讨论】:

  • @smac2020 感谢您的建议,但我的问题与 AJAX 无关..?
  • 如果您右键单击并检查,您将看到错误控制台消息。拒绝执行内联脚本,因为它违反了以下内容安全策略指令:“default-src 'none'”。启用内联执行需要“unsafe-inline”关键字、散列或随机数。此外,对于正确的 HTML,您应该有您的按钮类型 submit 并在您的表单上有一个 onSubmit。在输入中按 Enter 时将避免执行默认输入帖子
  • 浏览器开发者工具怎么说?提示:CORS 可能会很痛苦。
  • 这个 JavaScript 看起来非常简单。您是否在浏览器中看到控制台错误 - 如果有,它们是什么?
  • @stdunbar, smac2020 感谢两位将我指向浏览器开发者工具 > 控制台(我不知道那里出现了错误)。我已经相应地更新了我的帖子,现在有一些东西要调试 - 谢谢!

标签: javascript html amazon-web-services


【解决方案1】:

嗯,我在这里学到了一些重要的经验教训:

  1. 调试(非响应式)JavaScript 的最佳方式是浏览器的更多工具 > 开发人员工具 > 控制台选项卡。没有这个,我就瞎了眼。
  2. 问题不在于 JavaScript,而在于我添加的安全标头。我在没有深入了解指令的情况下遵循了 this AWS article,他们阻止了我的 JavaScript。
  3. 内联 JavaScript 不好! 确保将所有脚本放入单独的文件中。也许这对你来说很明显,但我不得不read this article to understand why。另外,我已经看到很多关于内联 JavaScript 的 Stack Overflow 问题,所以我怀疑这是否真的众所周知......
  4. 使用Mozilla ObservatoryGoogle's CSP Evaluator 检查并提高您网站的安全性。

最后,我使用了以下 Content-Security-Policy 标头:

default-src 'none';
img-src 'self';
script-src 'self';
style-src 'self';
require-trusted-types-for 'script';
base-uri 'none';
form-action 'self';
frame-ancestors 'none'

当然,您应该根据您网站的需要来定制它。说真的,just spend the 30 minutes to thoroughly understand this article,免得你以后头疼。

更新:

我忘记包含 Google reCAPTCHA 的权限,所以我进一步更新了 CSP 的 script-src 如下:

default-src 'none';
script-src 'self' https://www.google.com/recaptcha/api.js;
img-src 'self'; [...etc...]

更新 2:

作为下面的 cmets 之一,require-trusted-types-for 指令确实应该被删除。

我还必须启用 recaptcha 和 AWS API Gateway,所以我的最终解决方案比我上面写的要复杂得多。这是以防万一它帮助别人:

default-src 'none';
connect-src AMAZON_API_GATEWAY;
img-src 'self';
font-src 'self' https://fonts.gstatic.com;
frame-src https://www.google.com/recaptcha/ https://recaptcha.google.com/recaptcha/;
script-src 'self' https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/;
style-src 'self' https://fonts.googleapis.com;
base-uri 'none';
form-action 'self';
frame-ancestors 'none'

【讨论】:

  • 为了避免真正的头痛 - 尽快删除 require-trusted-types-for 指令。如果misused,这个指令it blocks很多javascript的构造:element.innerHTML =...document.write()setAttribute('onClick', ...)createElement('script')等。在最新的Chrome浏览器中检查你的网页。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 1970-01-01
相关资源
最近更新 更多