如何让 Cloudfront 在 POST 上返回非缓存的源页面



我正在使用 Cloudfront 为 Heroku(免费套餐(上托管的 Flask 应用程序提供自定义域和关联的 TLS 证书。 我有一个表单,该表单从用户那里 POST 输入,由 Flask 应用程序处理。 基于输入和成功的表单验证,将呈现一个新模板,其中将收集进一步的用户信息(即两步表单(。

在本地测试或直接访问 Heroku 应用程序 (example_app.herokuapp.com( 时,一切正常。 当我通过自定义 URL/Cloudfront 进行测试时,页面只是重新加载第一个表单步骤。

我想将 Cloudfront 用于自定义域/证书,但我不太担心缓存 - 很高兴拥有,但我宁愿我的应用程序正常工作!

我尝试过:

1( 在 Cloudfront 分发>>行为上,我尝试禁用所有缓存并允许开机自检:

  • 允许的 HTTP 方法:GET、HEAD、OPTIONS、PUT、POST、PATCH、DELETE

  • 基于所选请求标头的缓存:全部

  • 对象缓存:自定义

  • 最小 TTL:0

  • 最大 TTL:0

  • 默认 TTL:0

  • 查询字符串转发和缓存:全部转发,基于全部缓存

2(在Flask应用程序中,我添加了代码以添加无缓存标头:

如此处所述和下面的代码。

@bp.after_request
def add_header(r):
r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
r.headers["Pragma"] = "no-cache"
r.headers["Expires"] = "0"
return r

这是我的烧瓶路线文件的一部分,它返回表单页面模板...

# Route for activation form page
@bp.route('/activate/', methods=['GET', 'POST'])
def activate():
form = ActivateForm()
if form.validate_on_submit():
# Get the details entered by the customer
email = form.email.data
value2 = form.value2.data
# Check that input is valid
result = check_valid(value2)
# if valid
if result['status'] == 1:
# do stuff to activate subscription and assign sub_id
# Redirect to sucessful activation page
return render_template('finish.html', title='Finalising your subscription', sub_id=sub_id, email=email)
# if the form isn't valid or hasn't been submitted...
return render_template('activate.html', title='Activate', form=form)

当我在本地测试或直接针对 Heroku (example_app.herokuapp.com 进行测试时,一切都按预期工作:

  • 在首次访问页面或表单内容无效时,将加载激活.html模板。

  • 提交有效表单后,将加载if result['status'] == 1:运行和完成.html模板中的说明。

注意:页面 URL 在两个表单步骤/加载之间不会更改。

但是,当我尝试通过 Cloudfront 访问该应用程序时:

  • 在首次访问页面时或表单内容无效时,激活.html模板将按预期加载。

  • 提交有效表单后,激活.html模板将再次加载,并且if result['status'] == 1:中的说明不会执行。

我尝试在 Cloudfront 和 Origin 应用程序上禁用缓存,但看起来 Cloudfront 仍在提供页面的缓存版本。

更新:进一步的测试表明,form.validate_on_submit()甚至form.is_submitted()的评估结果均为 False。 这解释了可观察到的操作,即页面只是重新加载表单,就好像它尚未提交一样。 我不明白为什么我会看到这种行为。 我已允许在 Cloudfront 分配上发布 POST,但我是否需要在 Cloudfront 上设置其他内容才能让它发送表单值? 还是 Origin Web 服务器(gunicorn 19.9.0(上的内容正在删除表单详细信息?

更新 2:我在应用程序中添加了Flask_cors@cross_origin(allow_headers=['Content-Type'])并将装饰器添加到测试路由中。 同样的问题仍然存在。 我不完全了解 CORS 问题,我以前从未使用过Flask_cors,但希望这已经排除了与 CORS 相关的问题。 如果更有经验的人认为这是一个与 CORS 相关的问题,我愿意对此进行更正。

更新 3(解决方法(:我用if request.method == 'POST':替换了form.validate_on_submit(),应用程序似乎正在运行。

然而:

  1. 我仍然不明白为什么表单没有返回更正。 谁能解释一下Cloudfront和Heroku应用程序/网络服务器之间可能发生的事情?

  2. 只使用if request.method == 'POST':有什么缺点吗? 手动替换表单验证的最佳做法是什么? 我是否需要验证(猜测是的,但我需要测试以查看是否可以在没有form.validate_on_submit()的情况下破坏应用程序(?

  3. 为什么form.validate_on_submit()form.is_submitted()返回 false,但我可以通过value2 = form.value2.data等访问所有表单值?

更新4:标记Flask-WFT,因为is_submitted()中可能存在某些问题。

从来没有弄清楚具体问题是什么。 我删除并重新创建了 Cloudfront,Flask-WFT is_submitted(( 开始按预期工作。 所以。。。也许我的原始配置具有类型或在某些方面有所不同?

这是当前的 Cloudfront 配置,如果它对任何人有帮助......

交付方式:网络

饼干记录:关闭

自定义 SSL 客户端支持:支持服务器名称指示 (SNI( 的客户端 - (推荐(

安全策略:TLSv1.2_2018

支持的 HTTP 版本: HTTP/1.1、HTTP/1.0

源协议策略:仅限 HTTPS

源响应超时:30

原产地吉普存活超时:5

查看器协议策略:将 HTTP 重定向到 HTTPS

转发查询字符串:是

相关内容

  • 没有找到相关文章

最新更新