如何让 Cloudfront 到 return non-cached POST 上的原始页面
How to get Cloudfront to return non-cached Origin page on POST
我正在使用 Cloudfront 为托管在 Heroku(免费套餐)上的 Flask 应用程序提供自定义域和关联的 TLS 证书。我有一个表单,其中 POSTs 来自用户的输入,由 Flask 应用程序处理。基于输入和成功的表单验证,呈现一个新模板,其中收集更多用户信息(即两步表单)。
在本地测试或直接访问 Heroku 应用程序时 (example_app.herokuapp.com) 一切正常。当我通过自定义 URL/Cloudfront 进行测试时,页面只是重新加载第一个表单步骤。
我想使用 Cloudfront 进行自定义 domain/cert 但我不太在意缓存 - 如果有它会很好,但我希望我的应用程序正常运行!
我尝试过的:
1) 关于 Cloudfront Distribution >> 行为我尝试禁用所有缓存并允许 POST:
允许的 HTTP 方法:GET、HEAD、OPTIONS、PUT、POST、PATCH、DELETE
基于所选请求的缓存Headers:全部
Object缓存:自定义
最小 TTL:0
最大 TTL:0
默认 TTL:0
Query String转发和缓存:全部转发,全部缓存
2) 在 Flask 应用程序中,我添加了代码以添加 no-cache header:
如 和下面的代码所述。
@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
这是我的 Flask Routes 文件的一部分,其中 return 是表单页面模板...
# 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) 进行测试时,一切都按预期工作:
初始页面访问或表单内容无效时,activate.html 模板加载。
提交有效表格后,if result['status'] == 1:
运行 和 finish.html 模板中的说明会加载。
注意:页面URL在两种形式steps/loads之间没有变化。
但是,当我尝试通过 Cloudfront 访问应用程序时:
在初始页面访问或表单内容无效时,activate.html 模板会按预期加载。
提交有效表单后,activate.html 模板再次加载,if result['status'] == 1:
中的指令不会执行。
我已经尝试在 Cloudfront 和 Origin 应用程序上禁用缓存,但看起来 Cloudfront 仍然在提供页面的缓存版本。
更新: 进一步的测试表明 form.validate_on_submit()
甚至 form.is_submitted()
都评估为 False。这解释了可观察到的操作,即页面只是重新加载表单,就好像表单尚未提交一样。我不明白为什么我会看到这种行为。我已经允许 POST 在 Cloudfront 分配上,但我是否需要在 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()
,应用程序似乎可以正常工作。
但是:
我仍然不明白为什么表格没有被 return 更正。谁能解释一下 Cloudfront 和 Heroku 之间可能发生的事情 App/webserver?
仅使用 if request.method == 'POST':
有什么缺点吗?手动替换表单验证的最佳做法是什么?我是否需要验证(猜测是,但我需要测试看看我是否可以在没有 form.validate_on_submit()
的情况下破坏应用程序)?
为什么 form.validate_on_submit()
和 form.is_submitted()
return false 但我可以通过 value2 = form.value2.data
等访问所有表单值?
更新 4: 标记 Flask-WFT,因为 is_submitted()
中可能存在错误。
从来没有弄清楚具体问题是什么。我删除并重新创建了 Cloudfront,Flask-WFT is_submitted() 开始按预期工作。所以...也许我的原始配置有一个类型或在某些方面有所不同?
这是当前的 Cloudfront 配置,如果它对任何人有帮助的话...
交付方式:网络
Cookie 记录:关闭
自定义 SSL 客户端支持:支持服务器名称指示 (SNI) 的客户端 -(推荐)
安全策略:TLSv1.2_2018
支持的 HTTP 版本:HTTP/1.1,HTTP/1.0
源协议策略:仅限 HTTPS
源响应超时:30
Origin Kepp-alive 超时:5
查看器协议策略:将 HTTP 重定向到 HTTPS
转发查询字符串:是
我正在使用 Cloudfront 为托管在 Heroku(免费套餐)上的 Flask 应用程序提供自定义域和关联的 TLS 证书。我有一个表单,其中 POSTs 来自用户的输入,由 Flask 应用程序处理。基于输入和成功的表单验证,呈现一个新模板,其中收集更多用户信息(即两步表单)。
在本地测试或直接访问 Heroku 应用程序时 (example_app.herokuapp.com) 一切正常。当我通过自定义 URL/Cloudfront 进行测试时,页面只是重新加载第一个表单步骤。
我想使用 Cloudfront 进行自定义 domain/cert 但我不太在意缓存 - 如果有它会很好,但我希望我的应用程序正常运行!
我尝试过的:
1) 关于 Cloudfront Distribution >> 行为我尝试禁用所有缓存并允许 POST:
允许的 HTTP 方法:GET、HEAD、OPTIONS、PUT、POST、PATCH、DELETE
基于所选请求的缓存Headers:全部
Object缓存:自定义
最小 TTL:0
最大 TTL:0
默认 TTL:0
Query String转发和缓存:全部转发,全部缓存
2) 在 Flask 应用程序中,我添加了代码以添加 no-cache header:
如
@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
这是我的 Flask Routes 文件的一部分,其中 return 是表单页面模板...
# 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) 进行测试时,一切都按预期工作:
初始页面访问或表单内容无效时,activate.html 模板加载。
提交有效表格后,
if result['status'] == 1:
运行 和 finish.html 模板中的说明会加载。
注意:页面URL在两种形式steps/loads之间没有变化。
但是,当我尝试通过 Cloudfront 访问应用程序时:
在初始页面访问或表单内容无效时,activate.html 模板会按预期加载。
提交有效表单后,activate.html 模板再次加载,
if result['status'] == 1:
中的指令不会执行。
我已经尝试在 Cloudfront 和 Origin 应用程序上禁用缓存,但看起来 Cloudfront 仍然在提供页面的缓存版本。
更新: 进一步的测试表明 form.validate_on_submit()
甚至 form.is_submitted()
都评估为 False。这解释了可观察到的操作,即页面只是重新加载表单,就好像表单尚未提交一样。我不明白为什么我会看到这种行为。我已经允许 POST 在 Cloudfront 分配上,但我是否需要在 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()
,应用程序似乎可以正常工作。
但是:
我仍然不明白为什么表格没有被 return 更正。谁能解释一下 Cloudfront 和 Heroku 之间可能发生的事情 App/webserver?
仅使用
if request.method == 'POST':
有什么缺点吗?手动替换表单验证的最佳做法是什么?我是否需要验证(猜测是,但我需要测试看看我是否可以在没有form.validate_on_submit()
的情况下破坏应用程序)?为什么
form.validate_on_submit()
和form.is_submitted()
return false 但我可以通过value2 = form.value2.data
等访问所有表单值?
更新 4: 标记 Flask-WFT,因为 is_submitted()
中可能存在错误。
从来没有弄清楚具体问题是什么。我删除并重新创建了 Cloudfront,Flask-WFT is_submitted() 开始按预期工作。所以...也许我的原始配置有一个类型或在某些方面有所不同?
这是当前的 Cloudfront 配置,如果它对任何人有帮助的话...
交付方式:网络
Cookie 记录:关闭
自定义 SSL 客户端支持:支持服务器名称指示 (SNI) 的客户端 -(推荐)
安全策略:TLSv1.2_2018
支持的 HTTP 版本:HTTP/1.1,HTTP/1.0
源协议策略:仅限 HTTPS
源响应超时:30
Origin Kepp-alive 超时:5
查看器协议策略:将 HTTP 重定向到 HTTPS
转发查询字符串:是