从Flask返回重定向到S3不会下载文件

时间:2023-02-06 00:05:22

I need to redirect to an S3 URL while setting some extra S3-related headers. The Flask route is returning a page with Redirecting to <url> and a clickable link, and the browser doesn't automatically redirect. Why isn't the redirect working?

我需要重定向到S3 URL,同时设置一些额外的S3相关标头。 Flask路由返回一个页面,其中包含重定向到 和可点击链接,浏览器不会自动重定向。为什么重定向不起作用?

@app.route("/download/<token>")
def download(token):
    ...
    response = redirect(download_url)
    response.headers = generate_s3_headers(key, md5)
    return response

I can download the file successfully using Requests.

我可以使用请求成功下载文件。

import requests
r = requests.get(download_url, headers=headers)

1 个解决方案

#1


1  

This is a compound problem. The immediate issue is that you're overwriting the Location header. However, if you fix that, headers aren't preserved when following redirects, so S3 won't get the headers.

这是一个复合问题。当前的问题是您正在覆盖Location标头。但是,如果您修复了此问题,则在关注重定向时不会保留标头,因此S3不会获取标头。

If you need to serve a resource from S3 with special headers, you need to download and pass on that file through your app, instead of redirecting users directly to it.

如果您需要使用特殊标头从S3提供资源,则需要通过应用程序下载并传递该文件,而不是直接将用户重定向到该文件。

stream = requests.get(url, headers=headers, stream=True)
response = app.response_class(r.iter_content())
response.headers.set('Content-Disposition', 'attachment')
return response

The following is an explanation of why overriding the Location header breaks the redirect, but isn't the solution to your specific issue.

以下是为什么覆盖Location标头会破坏重定向的原因,但不是您特定问题的解决方案。

A redirect response includes the Location header. This is how the browser knows where to go next. redirect sets that header as well as generating a link in case the browser doesn't follow it. You're completely replacing all the headers though, removing Location. Use headers.extend to add your extra headers, rather than replacing them completely.

重定向响应包括Location标头。这就是浏览器知道下一步该去哪里的方法。重定向设置该标头以及在浏览器不遵循它时生成链接。你完全取代了所有标题,删除了位置。使用headers.extend添加额外的标头,而不是完全替换它们。

response = redirect(download_url)
response.headers.extend(generate_s3_headers(key, md5))
return response

#1


1  

This is a compound problem. The immediate issue is that you're overwriting the Location header. However, if you fix that, headers aren't preserved when following redirects, so S3 won't get the headers.

这是一个复合问题。当前的问题是您正在覆盖Location标头。但是,如果您修复了此问题,则在关注重定向时不会保留标头,因此S3不会获取标头。

If you need to serve a resource from S3 with special headers, you need to download and pass on that file through your app, instead of redirecting users directly to it.

如果您需要使用特殊标头从S3提供资源,则需要通过应用程序下载并传递该文件,而不是直接将用户重定向到该文件。

stream = requests.get(url, headers=headers, stream=True)
response = app.response_class(r.iter_content())
response.headers.set('Content-Disposition', 'attachment')
return response

The following is an explanation of why overriding the Location header breaks the redirect, but isn't the solution to your specific issue.

以下是为什么覆盖Location标头会破坏重定向的原因,但不是您特定问题的解决方案。

A redirect response includes the Location header. This is how the browser knows where to go next. redirect sets that header as well as generating a link in case the browser doesn't follow it. You're completely replacing all the headers though, removing Location. Use headers.extend to add your extra headers, rather than replacing them completely.

重定向响应包括Location标头。这就是浏览器知道下一步该去哪里的方法。重定向设置该标头以及在浏览器不遵循它时生成链接。你完全取代了所有标题,删除了位置。使用headers.extend添加额外的标头,而不是完全替换它们。

response = redirect(download_url)
response.headers.extend(generate_s3_headers(key, md5))
return response